========================= original problem ========================= the biggest problem caused by early class binding is that it's unfriendly to opcode cachers. parent1.php class P { function __construct() { echo "parent2"; } } include "child.php" ========== parent2.php class P { function __construct() { echo "parent2"; } } include "child.php" ========== child.php class child extends P { } new child(); without opcode cacher, when parent1.php is requested, "parent1" is echoed, while parent2.php is requested "parent2" will be echoed. but with opcode cachers, it always use the echo from first requested/cached class P because when class child is being cached, it's after "early class binding" and is binded with its parent class P, the binding will not be done again after the child class is restored from cache
========================= other problems ========================= read the sample coe first: class MyException extends Exception { } early class binding is done at compile time and opcode cachers will only get binded not raw classes the problem is that, the binded class MyException is has so many handler pointers copied (inherited) from internal class Exception. it's hard for a opcode cacher to cache such opcode data to disk, or share with another instance of php which is not forked from the same parent php process due to possible symbol relocation. ========================= compatibility issue without early class binding ========================= iirc the early class binding was removed but added back later due to back compatibility issue: if the class is early binded, code before class declaration can use class new Foo(); // works class Foo // early binding at compile time { } but when there's no early binding new Foo(); // error, undefined class class Foo { } // late class binding is done here at runtime ========================= solution proposal ========================= solution a: forget the back compatibility issue, early class binding was deprecated and it's now gone. solution b: add an api that allow extension/zend_extension disable early class binding let opcode cachers decide to do nothing (which mean the user should accept that, the early binding is gone), or to redo the binding after restore from cache but before execution. when no extension use this api, no behavior change. pitfall for solution b: opcode cachers have to write their own scanner to figure out which classes should be early binded and which opline should be replaced with NOP solution c: like solution b, but ZendEngine do most of the work, for example: remember all the position/pointer to opline that might be replaced with NOP, return from zend_compile_file or zend_compile_string so opcode cachers will catch it. do early binding after zend_compile_file/string, which also mean after opcode cacher stuff Tips for those don't know zend_compile_file/string: zend_compile_file/string is a pointer that can be overloaded by extension/zend_extension so one can hook into the compile time ========================= PS ========================= XCache tricked to disable early class binding by emptying CG(class_table) before and restore it after compile so the compiler won't see any class that isn't in the same file. the reason i bring up this topic again before PHP_5_3 is out is becuase 5.3 namespace patch breaks the XCache trick and i find it no way to trick without changing php source: 5.3 namespace code will check for CG(class_table) and see if a class is internal class to generate different code. namespace ns; e.g.: class b extends Exception // will check ::Exception at runtime { } class a extends c // always ns::c { } with XCache enabled: class b extends Exception // always ns::Exception because there's no such internal class at compile time due to XCache trick. sorry for the long post so i mark the sections with ===s that will help your navigation -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php