ID: 39868 User updated by: jb at ez dot no Reported By: jb at ez dot no -Status: Feedback +Status: Open Bug Type: Unknown/Other Function Operating System: Kubuntu 6.10 PHP Version: 5.2.0 New Comment:
You don't think it is a problem that the destructor (for Master) is called while the constructor (for Master) is never called? In this example neither the constructor or the destructor should be called since an exception is thrown in the Child class, ie. the new Master() expression should never be processed. The problem seems to be that PHP actually allocates the object for Master and then delays the call to construct until the parameters are prepared (which makes sense, except the allocation). Then when the exception is thrown PHP will cleanup all variables/objects, it then sees the allocated object and tries the destructor, In a good object oriented language you would never call the destructor unless the constructor was called and was completed 100%. Previous Comments: ------------------------------------------------------------------------ [2006-12-18 14:46:29] [EMAIL PROTECTED] I don't see anything wrong here. With "$b = new Child(); $a = new Master( $b );" the second line does not get executed, of course you won't see any of Master methods called. But "$a = new Master( new Child() );" is totally different case - Master::__construct() is called, you don't see the output because the exception is thrown just before you print it. ------------------------------------------------------------------------ [2006-12-18 14:31:19] jb at ez dot no Description: ------------ It is possible for PHP to call the __destruct() on an object allthough __construct() was never called. This seems to happen when having nested object creations and the inner one throws and exception in the constructor. The attached reproducable code shows the problem: Child::__construct() [Child] Master::__destruct() [Master] If the last line is changed to: $b = new Child(); $a = new Master( $b ); it works of course. In general destructors should never be called if the constructor was not called or even if it did not finish. Reproduce code: --------------- class Master { public function __construct( $child ) { echo __CLASS__, "::__construct() [", get_class( $this ), "]\n"; } public function __destruct() { echo __CLASS__, "::__destruct() [", get_class( $this ), "]\n"; } } class Child { public function __construct() { echo __CLASS__, "::__construct() [", get_class( $this ), "]\n"; throw new Exception( "Child failure" ); } public function __destruct() { echo __CLASS__, "::__destruct() [", get_class( $this ), "]\n"; } } $a = new Master( new Child() ); Expected result: ---------------- Child::__construct() [Child] Actual result: -------------- Child::__construct() [Child] Master::__destruct() [Master] ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=39868&edit=1