Question

I've illustrated an example of the issue I'm running into. To my (probably incorrect) way of thinking, a caught exception should not cause a loop to break; that is to say, the loop encounters an exception, throws it, the exception is handled, and then the loop should continue, no? The problem is, this isn't what's happening, the loop is breaking upon throwing its first exception even though it's in a try/catch block. What am I misunderstanding here? How can I make this work as expected (I'd expect to see both exceptions handled and a,b,c,d properties set).

I've created a demo here: http://codepad.org/ZOm8cOzd

Code:

<?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 );

Output:

*** 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
}
Was it helpful?

Solution

Well - the issue is that apparently exceptions "just don't work this way". I solved the problem like this, hopefully it helps someone:

http://codepad.org/ZhdGjJi6

Code:

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 );

Output:

*** 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) {
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top