为什么捕获的异常仍会打破循环?我们怎样才能让它继续下去?

时间:2014-02-17 10:13:08

标签: php loops exception-handling

我已经举例说明了我遇到的问题。对于我(可能是不正确的)思维方式,一个被捕获的异常不应该导致循环中断;也就是说,循环遇到异常,抛出它,处理异常,然后循环应该继续,不是吗?问题是,这不是正在发生的事情,即使它在try / catch块中,循环也会在抛出第一个异常时中断。我在这里误解了什么?如何使这项工作按预期工作(我希望看到处理两个异常并设置a,b,c,d属性)。

我在这里创建了一个演示: http://codepad.org/ZOm8cOzd

代码:

<?php

abstract class xGrandparent {
    public function __construct( $params = array() ){
        foreach( $params as $k => $v ){
            if( property_exists($this, $k) ){
                $this->$k = $v;
            } else {
                switch($k){
                    case 'e':
                        throw new Exception('exception e', 111);
                        break;
                    case 'f':
                        throw new Exception('exception f', 222);
                        break;
                }
            }
        }
    }
}

abstract class xParent extends xGrandparent {
    protected
        $c,
        $d
    ;

    public function __construct( $params = array() ){
        try {
            parent::__construct( $params );
        } catch ( Exception $e ){
            if( $e->getCode() == 222 ){
               echo "*** parent caught exception \n";
            } else {
               throw $e;
            }
        }
    }
}

class xChild extends xParent {
    protected 
        $a,
        $b
    ;

    public function __construct( $params = array() ){
        try {
            parent::__construct( $params );
        } catch ( Exception $e ){
            echo "*** child caught exception \n";
        }
    }

}


$test = new xChild(array(
    'a' => 'a val',
    'c' => 'c val',
    'e' => 'e val',
    'f' => 'f val',
    'b' => 'b val',
    'd' => 'd val',

));

var_dump( $test );

输出:

*** child caught exception 
object(xChild)#1 (4) {
  ["a:protected"]=>
  string(5) "a val"
  ["b:protected"]=>
  NULL
  ["c:protected"]=>
  string(5) "c val"
  ["d:protected"]=>
  NULL
}

1 个答案:

答案 0 :(得分:1)

嗯 - 问题是显然例外“只是不这样做”。我解决了这个问题,希望它可以帮到某人:

http://codepad.org/ZhdGjJi6

代码:     

abstract class xGrandparent {
    protected
        $propertySettingExceptions = array()
    ;

    public function __construct( $params = array() ){
        foreach( $params as $k => $v ){
            if( property_exists($this, $k) ){
                $this->$k = $v;
            } else {
                try {
                    switch($k){
                        case 'e':
                            throw new Exception('exception e', 111);
                            break;
                        case 'f':
                            throw new Exception('exception f', 222);
                            break;
                    }
                } catch (Exception $e){
                    $this->propertySettingExceptions[] = $e;        
                }
            }
        }
    }
}

abstract class xParent extends xGrandparent {
    protected
        $c,
        $d
    ;

    public function __construct( $params = array() ){
        parent::__construct( $params );

        if( sizeof($exceptions = &$this->propertySettingExceptions) ){
            foreach( $exceptions as $k => $exception ){
                switch( $exception->getCode() ){
                    case 222:
                        echo "*** parent caught exception \n";
                        unset($exceptions[$k]);
                        break;
                }
            }
        }
    }
}

class xChild extends xParent {
    protected 
        $a,
        $b
    ;

    public function __construct( $params = array() ){
        parent::__construct( $params );

        if( sizeof($exceptions = &$this->propertySettingExceptions) ){
            foreach( $exceptions as $k => $exception ){
                switch( $exception->getCode() ){
                    case 111:
                        echo "*** child caught exception \n";
                        unset($exceptions[$k]);
                        break;
                }
            }
        }
    }

}


$test = new xChild(array(
    'a' => 'a val',
    'c' => 'c val',
    'e' => 'e val',
    'f' => 'f val',
    'b' => 'b val',
    'd' => 'd val',

));

var_dump( $test );

输出:

*** parent caught exception 
*** child caught exception 
object(xChild)#1 (5) {
  ["a:protected"]=>
  string(5) "a val"
  ["b:protected"]=>
  string(5) "b val"
  ["c:protected"]=>
  string(5) "c val"
  ["d:protected"]=>
  string(5) "d val"
  ["propertySettingExceptions:protected"]=>
  array(0) {
  }
}