RE: [PHP-DEV] [patch] Late static bindings (LSB)
Hi Robin, Thank you for catching this issue. static:: make no sense in compile-time constants. I've just forbidden it there. Thanks. Dmitry. -Original Message- From: Robin Fernandes [mailto:[EMAIL PROTECTED] Sent: Friday, September 28, 2007 6:45 PM To: internals@lists.php.net Cc: Stanislav Malyshev; Baptiste Autin; Zoe Slattery; Dmitry Stogov; Marcus Boerger; Lukas Kahwe Smith; Michael Lively; Etienne Kneuss; Andi Gutmans Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB) Sorry to persist with this, but I think it could be really useful to clarify the meaning of static:: outside of method bodies... particularly since parent:: and self:: can already behave very strangely in such scenarios (see http://news.php.net/php.internals/32443 ). For example, I find the following behaviour with the current patch counter-intuitive: ?php // NOTE: X is not related to A. class X { const MY_CONST = I am completely unrelated to class A.; static function createA() { new A; // triggers initialiser evaluation } } class A { const MY_CONST = const A; public $p = static::MY_CONST; static function getInstance() { return new A; } } // First instantiate A inside X. This causes A's properties' // default values to be evaluated within X's scope. X::createA(); // Now that A's default values have been evaluated, // behaviour is as if any new instance of A treats // the occurrence of static:: on line 12 to mean X. // Instantiate A inside A: $a = A::getInstance(); var_dump($a-p);// has value of X::MY_CONST. // Instantiate A at global scope: $a = new A(); var_dump($a-p);// has value of X::MY_CONST. ? Actual output: string(37) I am completely unrelated to class A. string(37) I am completely unrelated to class A. Some thoughts: - static:: could simply be forbidden in all class property/constant default values. - Any occurrences of static:: in instance property default values could behave as if they were in the constructor, but be forbidden in static property and constant initialisers. - Other ideas? Also, there are some questions around reflection. All of the following A::reflect*() calls cause a fatal error like: PHP Fatal error: Undefined class constant 'MY_CONST' in %s on line %d ?php class A { const MY_CONST = const A; const C1 = static::MY_CONST; static function f($a = static::MY_CONST) { return $a; } static function f2() { static $x = static::MY_CONST; } static function reflectConst() { $rc = new ReflectionClass('A'); var_dump($rc-getConstant('C1')); } static function reflectArg() { $rm = new ReflectionMethod('A::f'); $rps = $rm-getParameters(); var_dump($rps[0]-getDefaultValue()); } static function reflectStat() { $rm = new ReflectionMethod('A::f2'); var_dump($rm-getStaticVariables()); } } A::reflectConst(); // fatal error A::reflectArg(); // fatal error A::reflectStat(); // fatal error ? Is this desirable? One could argue that the reflection calls emanate from A::, so static:: could be resolved accordingly. This test case suggests that static:: is in fact being bound to the ReflectionClass class itself (since ReflectionClass::IS_FINAL===64) : ?php class A { const IS_FINAL = This string is not integer sixty-four; const C1 = static::IS_FINAL; } $rc = new ReflectionClass('A'); $rc-getConstant('C1'); // trigger evaluation of A::C1 var_dump(A::C1); ? Actual output: int(64) Kind regards, Robin On 27/09/2007, Jingcheng Zhang [EMAIL PROTECTED] wrote: Hello, static methods seem exactly like dynamic binded methods now, is there any chance that abstract static function being restored from E_STRICT limitation? Currently it is allowed in interfaces, but forbidden in abstract class, I don't know why php implements static method in this way, this seems strange.. Thanks! On 9/27/07, Stanislav Malyshev [EMAIL PROTECTED] wrote: So, if I understand you well, Stanislas, you are personally not much into static:: but more into making that sort of code working : interface iC { public $structure; } abstract class A implements iC { public function display() { echo self::$structure; } } class B extends A { static public $structure = This is a string.; } $b = new B(); $b-display(); No, I don't think we should make interfaces with variables, I'm just telling that the code before had API that not allowed correctly enforce its requirements. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Sorry to persist with this, but I think it could be really useful to clarify the meaning of static:: outside of method bodies... particularly since parent:: and self:: can already behave very strangely in such scenarios (see http://news.php.net/php.internals/32443 ). For example, I find the following behaviour with the current patch counter-intuitive: ?php // NOTE: X is not related to A. class X { const MY_CONST = I am completely unrelated to class A.; static function createA() { new A; // triggers initialiser evaluation } } class A { const MY_CONST = const A; public $p = static::MY_CONST; static function getInstance() { return new A; } } // First instantiate A inside X. This causes A's properties' // default values to be evaluated within X's scope. X::createA(); // Now that A's default values have been evaluated, // behaviour is as if any new instance of A treats // the occurrence of static:: on line 12 to mean X. // Instantiate A inside A: $a = A::getInstance(); var_dump($a-p);// has value of X::MY_CONST. // Instantiate A at global scope: $a = new A(); var_dump($a-p);// has value of X::MY_CONST. ? Actual output: string(37) I am completely unrelated to class A. string(37) I am completely unrelated to class A. Some thoughts: - static:: could simply be forbidden in all class property/constant default values. - Any occurrences of static:: in instance property default values could behave as if they were in the constructor, but be forbidden in static property and constant initialisers. - Other ideas? Also, there are some questions around reflection. All of the following A::reflect*() calls cause a fatal error like: PHP Fatal error: Undefined class constant 'MY_CONST' in %s on line %d ?php class A { const MY_CONST = const A; const C1 = static::MY_CONST; static function f($a = static::MY_CONST) { return $a; } static function f2() { static $x = static::MY_CONST; } static function reflectConst() { $rc = new ReflectionClass('A'); var_dump($rc-getConstant('C1')); } static function reflectArg() { $rm = new ReflectionMethod('A::f'); $rps = $rm-getParameters(); var_dump($rps[0]-getDefaultValue()); } static function reflectStat() { $rm = new ReflectionMethod('A::f2'); var_dump($rm-getStaticVariables()); } } A::reflectConst(); // fatal error A::reflectArg(); // fatal error A::reflectStat(); // fatal error ? Is this desirable? One could argue that the reflection calls emanate from A::, so static:: could be resolved accordingly. This test case suggests that static:: is in fact being bound to the ReflectionClass class itself (since ReflectionClass::IS_FINAL===64) : ?php class A { const IS_FINAL = This string is not integer sixty-four; const C1 = static::IS_FINAL; } $rc = new ReflectionClass('A'); $rc-getConstant('C1'); // trigger evaluation of A::C1 var_dump(A::C1); ? Actual output: int(64) Kind regards, Robin On 27/09/2007, Jingcheng Zhang [EMAIL PROTECTED] wrote: Hello, static methods seem exactly like dynamic binded methods now, is there any chance that abstract static function being restored from E_STRICT limitation? Currently it is allowed in interfaces, but forbidden in abstract class, I don't know why php implements static method in this way, this seems strange.. Thanks! On 9/27/07, Stanislav Malyshev [EMAIL PROTECTED] wrote: So, if I understand you well, Stanislas, you are personally not much into static:: but more into making that sort of code working : interface iC { public $structure; } abstract class A implements iC { public function display() { echo self::$structure; } } class B extends A { static public $structure = This is a string.; } $b = new B(); $b-display(); No, I don't think we should make interfaces with variables, I'm just telling that the code before had API that not allowed correctly enforce its requirements. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- Best regards, Jingcheng Zhang Room 304, Dormitory 26 of Yuquan Campus, Zhejiang University P.R.China -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP-DEV] [patch] Late static bindings (LSB)
People generally prefer compile-time control which is derived from definition rather than per-instance runtime control (implementing interface vs. checking each time if class has certain methods). It's me again, sorry. So, if I understand you well, Stanislas, you are personally not much into static:: but more into making that sort of code working : interface iC { public $structure; } abstract class A implements iC { public function display() { echo self::$structure; } } class B extends A { static public $structure = This is a string.; } $b = new B(); $b-display(); If so, what's the problem? Is there a technical difficulty of implementation behind? Or is it because we are unsure whether all the people asking for LSB would be satisfied with that way? BTW, here's a funny sort of polymorphism with static members that already runs great with the actual PHP release: interface iC { function getStructure(); } abstract class A implements iC { public function display() { echo $this-getStructure(); } } abstract class B extends A { static public $structure = This is a string from B.; } class C extends B { static public $structure = This is a string from C.; public function getStructure() { return self::$structure; } } $c = new C(); $c-display(); Remove the definition of $structure in C, and the one in B will apply. I suppose Michael Lively's example would be solved (the one with the TableSelectQueries), if it could work the same way in a fully static context (and without the help of an additional method like getStructure) ... Right ? Baptiste -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Hello, if I understand you correctly, you want to radically change the behavior of self:: ? This is not doable as it would break tons of scripts! Regards On 9/27/07, Baptiste Autin [EMAIL PROTECTED] wrote: People generally prefer compile-time control which is derived from definition rather than per-instance runtime control (implementing interface vs. checking each time if class has certain methods). It's me again, sorry. So, if I understand you well, Stanislas, you are personally not much into static:: but more into making that sort of code working : interface iC { public $structure; } abstract class A implements iC { public function display() { echo self::$structure; } } class B extends A { static public $structure = This is a string.; } $b = new B(); $b-display(); If so, what's the problem? Is there a technical difficulty of implementation behind? Or is it because we are unsure whether all the people asking for LSB would be satisfied with that way? BTW, here's a funny sort of polymorphism with static members that already runs great with the actual PHP release: interface iC { function getStructure(); } abstract class A implements iC { public function display() { echo $this-getStructure(); } } abstract class B extends A { static public $structure = This is a string from B.; } class C extends B { static public $structure = This is a string from C.; public function getStructure() { return self::$structure; } } $c = new C(); $c-display(); Remove the definition of $structure in C, and the one in B will apply. I suppose Michael Lively's example would be solved (the one with the TableSelectQueries), if it could work the same way in a fully static context (and without the help of an additional method like getStructure) ... Right ? Baptiste -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- Etienne Kneuss http://www.colder.ch Men never do evil so completely and cheerfully as when they do it from a religious conviction. -- Pascal
RE: [PHP-DEV] [patch] Late static bindings (LSB)
You mean, tons of PHP scripts? It would just allow some non-working code (fatal error) to run, by extending the scope of self::. So what could it break? And if you add the obligation to implement an interface (probably under-used in PHP), it is even less likely that it raises side effects. No ? -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Etienne Kneuss Sent: jeudi 27 septembre 2007 01:11 To: Baptiste Autin Cc: Stanislav Malyshev; Zoe Slattery; Dmitry Stogov; Marcus Boerger; Lukas Kahwe Smith; Michael Lively; internals@lists.php.net; Andi Gutmans Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB) Hello, if I understand you correctly, you want to radically change the behavior of self:: ? This is not doable as it would break tons of scripts! Regards On 9/27/07, Baptiste Autin [EMAIL PROTECTED] wrote: People generally prefer compile-time control which is derived from definition rather than per-instance runtime control (implementing interface vs. checking each time if class has certain methods). It's me again, sorry. So, if I understand you well, Stanislas, you are personally not much into static:: but more into making that sort of code working : interface iC { public $structure; } abstract class A implements iC { public function display() { echo self::$structure; } } class B extends A { static public $structure = This is a string.; } $b = new B(); $b-display(); If so, what's the problem? Is there a technical difficulty of implementation behind? Or is it because we are unsure whether all the people asking for LSB would be satisfied with that way? BTW, here's a funny sort of polymorphism with static members that already runs great with the actual PHP release: interface iC { function getStructure(); } abstract class A implements iC { public function display() { echo $this-getStructure(); } } abstract class B extends A { static public $structure = This is a string from B.; } class C extends B { static public $structure = This is a string from C.; public function getStructure() { return self::$structure; } } $c = new C(); $c-display(); Remove the definition of $structure in C, and the one in B will apply. I suppose Michael Lively's example would be solved (the one with the TableSelectQueries), if it could work the same way in a fully static context (and without the help of an additional method like getStructure) ... Right ? Baptiste -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- Etienne Kneuss http://www.colder.ch Men never do evil so completely and cheerfully as when they do it from a religious conviction. -- Pascal -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
So, if I understand you well, Stanislas, you are personally not much into static:: but more into making that sort of code working : interface iC { public $structure; } abstract class A implements iC { public function display() { echo self::$structure; } } class B extends A { static public $structure = This is a string.; } $b = new B(); $b-display(); No, I don't think we should make interfaces with variables, I'm just telling that the code before had API that not allowed correctly enforce its requirements. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Hello, static methods seem exactly like dynamic binded methods now, is there any chance that abstract static function being restored from E_STRICT limitation? Currently it is allowed in interfaces, but forbidden in abstract class, I don't know why php implements static method in this way, this seems strange.. Thanks! On 9/27/07, Stanislav Malyshev [EMAIL PROTECTED] wrote: So, if I understand you well, Stanislas, you are personally not much into static:: but more into making that sort of code working : interface iC { public $structure; } abstract class A implements iC { public function display() { echo self::$structure; } } class B extends A { static public $structure = This is a string.; } $b = new B(); $b-display(); No, I don't think we should make interfaces with variables, I'm just telling that the code before had API that not allowed correctly enforce its requirements. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- Best regards, Jingcheng Zhang Room 304, Dormitory 26 of Yuquan Campus, Zhejiang University P.R.China
Re: [PHP-DEV] [patch] Late static bindings (LSB)
On 20/09/2007, Stanislav Malyshev [EMAIL PROTECTED] wrote: I think we better spend time on figuring out the concept and then do the patch than first do the patch and then discover we don't know how it was supposed to work :) Here's a question that I think hasn't been discussed and isn't covered by the test cases in the patch: will static:: have a meaning in property and constant declarations? e.g.: ? class A { const MY_CONST = const A; public $p = static::MY_CONST; } class B extends A { const MY_CONST = const B; } $a = new A(); $b = new B(); var_dump($a::p, $b::p); ? One reason I ask is that in php5.2, self:: and parent:: can (imho) act counter-intuitively in property declarations. They do not always behave as if they were bound at compile time. See test case below and http://news.php.net/php.internals/31961 for more details. (if these inconsistencies are bugs, please let me know and I'll happily raise them on bugzilla) ?php class A { const MY_CONST = 'MY_CONST_A'; public static $inheritedStatic = self::MY_CONST; public $inheritedProp = self::MY_CONST; const INHERITED_CONST = self::MY_CONST; public static function inheritedStaticMethod() { return self::MY_CONST; } public function inheritedMethod() { return self::MY_CONST; } } class B extends A { const MY_CONST = 'MY_CONST_B'; } echo \n Static Properties:\n; new B; // !!! Removing this line changes behaviour !!! echo- In A: ; var_dump(A::$inheritedStatic); echo- In B: ; var_dump(B::$inheritedStatic); echo \n Instance Properties\n; $a = new A; $b = new B; echo- In A: ; var_dump($a-inheritedProp); echo- In B: ; var_dump($b-inheritedProp); echo \n Constants:\n; echo- In A: ; var_dump(A::INHERITED_CONST); echo- In B: ; var_dump(B::INHERITED_CONST); echo \n Static call:\n; echo- From A: ; var_dump(A::inheritedStaticMethod()); echo- From B: ; var_dump(B::inheritedStaticMethod()); echo \n Instance call:\n; echo- From A: ; var_dump($a-inheritedMethod()); echo- From B: ; var_dump($b-inheritedMethod()); ? -- Actual Output on php5 -- Static Properties: - In A: string(10) MY_CONST_B - In B: string(10) MY_CONST_B Instance Properties - In A: string(10) MY_CONST_A - In B: string(10) MY_CONST_B Constants: - In A: string(10) MY_CONST_A - In B: string(10) MY_CONST_B Static call: - From A: string(10) MY_CONST_A - From B: string(10) MY_CONST_A Instance call: - From A: string(10) MY_CONST_A - From B: string(10) MY_CONST_A -- Expected output assuming self:: is bound at compile time -- Static Properties: - In A: string(10) MY_CONST_A - In B: string(10) MY_CONST_A Instance Properties - In A: string(10) MY_CONST_A - In B: string(10) MY_CONST_A Constants: - In A: string(10) MY_CONST_A - In B: string(10) MY_CONST_A Static call: - From A: string(10) MY_CONST_A - From B: string(10) MY_CONST_A Instance call: - From A: string(10) MY_CONST_A - From B: string(10) MY_CONST_A Kind regards, Robin Fernandes -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
On 9/24/07, Michael Lively [EMAIL PROTECTED] wrote: The very phrase late static binding is an oxymoron of sorts :) that's because the term we use is not correct… :) it would be better to say late binding of static methods -- Alexey Zakhlestin http://blog.milkfarmsoft.com/
RE: [PHP-DEV] [patch] Late static bindings (LSB)
If you mean Client's $structure, the you have to use static::$structure and it should work. However it's quite a bad design here since you have no way to ensure class inheriting from Entity would have $structure. Couldn't I write: isset(static::$structure) ? BTW, sorry for my recent vulgar intrusions on PHP internal forum. I know I am not skilled enough for it, I should have read more carefully some previous posts, and I am just a big redneck. Mea culpa :) So this will be my very last (and so much naïve) question: do you know how people cope with it in other OO languages? -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Couldn't I write: isset(static::$structure) ? You could, but that's only runtime. People generally prefer compile-time control which is derived from definition rather than per-instance runtime control (implementing interface vs. checking each time if class has certain methods). So this will be my very last (and so much naïve) question: do you know how people cope with it in other OO languages? AFAIK there are not many languages which allow you to do non-static static calls... I see no way of doing it in Java or C++ - please correct me if I'm wrong. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
- Original Message - From: Stanislav Malyshev [EMAIL PROTECTED] To: Baptiste Autin [EMAIL PROTECTED] Cc: 'Zoe Slattery' [EMAIL PROTECTED]; 'Dmitry Stogov' [EMAIL PROTECTED]; 'Marcus Boerger' [EMAIL PROTECTED]; 'Lukas Kahwe Smith' [EMAIL PROTECTED]; 'Michael Lively' [EMAIL PROTECTED]; 'Etienne Kneuss' [EMAIL PROTECTED]; internals@lists.php.net; 'Andi Gutmans' [EMAIL PROTECTED] Sent: Sunday, September 23, 2007 3:39 PM Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB) Couldn't I write: isset(static::$structure) ? You could, but that's only runtime. People generally prefer compile-time control which is derived from definition rather than per-instance runtime control (implementing interface vs. checking each time if class has certain methods). So this will be my very last (and so much naïve) question: do you know how people cope with it in other OO languages? AFAIK there are not many languages which allow you to do non-static static calls... I see no way of doing it in Java or C++ - please correct me if I'm wrong. The only languages I have seen that allow things like this seem to trend more towards prototype based languages. Though it may very well be that I don't know what terminology to look for. The very phrase late static binding is an oxymoron of sorts :). In any case I do want to be sure to say that just because the exact concept is lacking in Java and C++ that is not a reason to discount it entirely. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- No virus found in this incoming message. Checked by AVG Free Edition. Version: 7.5.488 / Virus Database: 269.13.30/1025 - Release Date: 9/23/2007 1:53 PM -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Like that one, ridiculous: static private function getStruct($class) { if(!(is_array(Entity::$struct) array_key_exists($class, Entity::$struct))) { eval(if(!isset(.$class.::\$structure)) self::array2xml('.$class.');); eval(Entity::\$struct[\$class] = new SimpleXMLElement( .$class.::\$structure);); } return Entity::$struct[$class]; } Do you understand what it does? Do you find it readable? Clean? I don't. Yet that's what I have to write in PHP. What you were trying to do I wonder? Maybe the problem arises in PHP because, as far as I know, there is no way to define a function as virtual, like in C++, and so you can't choose between static lookup or dynamic lookup. In C++, as far as I know, there's no such thing as static virtual function. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP-DEV] [patch] Late static bindings (LSB)
You could see about 20 tests with the latest patch. 2 of them especially to show inheritance problem. Thanks. Dmitry. -Original Message- From: Zoe Slattery [mailto:[EMAIL PROTECTED] Sent: Thursday, September 20, 2007 10:54 PM To: Stanislav Malyshev Cc: Dmitry Stogov; 'Marcus Boerger'; 'Lukas Kahwe Smith'; 'Michael Lively'; 'Etienne Kneuss'; internals@lists.php.net; 'Andi Gutmans' Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB) Stanislav Malyshev wrote: So we have at least three different views on concept. It seems that patch will be delayed again. :( I think we better spend time on figuring out the concept and then do the patch than first do the patch and then discover we don't know how it was supposed to work :) How about writing the test cases first - and then the patch? -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
class TableSelectExplainBuilder extends TableSelectBuilder { static protected function buildSelectQuery() { return EXPLAIN .parent::buildSelectQuery(); } } Why not do static:: instead of parent:: here? -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Now, let's say the base class is called Entity. And let's say I have an inherited class called Client: Abstract Class Entity { function read() {} function delete() {} ... } Class Client extends Entity { public $id; public $first_name; public $last_name; static public $structure = ? structure of Client ?; } Now, imagine you are programming the delete function in class Entity. And you have to use the $structure variable. If you mean Client's $structure, the you have to use static::$structure and it should work. However it's quite a bad design here since you have no way to ensure class inheriting from Entity would have $structure. Since all the objects you are manipulating are Client objects (or other inherited table objects), it would be logical to write: parent::$structure It won't be since Entity has no parent, so delete() in Entity definitely can't use this keyword. Personally, I think one should give the programmer the choice, exactly like the programmer is given the choice between __CLASS__ (now, like it is written steadily in the code) and get_parent_class() (at run time, like objects are really instantiated). __CLASS__ returns name of the class, get_parent_class() is the name of parent class, those are entirely different things, nothing to do with compiler/run time. Class always has one name and one parent or none. I may be wrong, but I think LSB occurs every time you need to do something in a RELATIVE way (get_parent_class(), parent::), because there is an What do you mean by RELATIVE? ambiguity upon what you consider as your reference, when you write something like parent::$structure. There's no any ambiguity - parent:: always means the name of the class you wrote after the keyword extends. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP-DEV] [patch] Late static bindings (LSB)
With static:: you are not able to call method of parent with the same name. Dmitry. -Original Message- From: Stanislav Malyshev [mailto:[EMAIL PROTECTED] Sent: Friday, September 21, 2007 12:03 PM To: Michael Lively Cc: Dmitry Stogov; 'Marcus Boerger'; 'Lukas Kahwe Smith'; 'Etienne Kneuss'; internals@lists.php.net; 'Andi Gutmans' Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB) class TableSelectExplainBuilder extends TableSelectBuilder { static protected function buildSelectQuery() { return EXPLAIN .parent::buildSelectQuery(); } } Why not do static:: instead of parent:: here? -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Hello Dmitry, this is a good idea imo. It sounds like the most natural solution - to me. marcus Thursday, September 20, 2007, 12:04:04 PM, you wrote: From technical point of view it is possible to propagate LSB with self::, parent::, and static:: and not with CLASS::. I think it may be a good compromise. Thanks. Dmitry. -Original Message- From: Stefan Walk [mailto:[EMAIL PROTECTED] Sent: Thursday, September 20, 2007 1:10 PM To: Dmitry Stogov; internals@lists.php.net Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB) Is it possible or feasible to distinguish betwenn parent:: and NameOfParentClass::? That would allow to push a call up while preserving the called name while not making Class:: mean different things depending on the location of the call, which is a very bad thing IMO (it's an effect that may not be desired). Regards, Stefan Best regards, Marcus -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP-DEV] [patch] Late static bindings (LSB)
__CLASS__ returns name of the class, get_parent_class() is the name of parent class, those are entirely different things, nothing to do with compiler/run time. Class always has one name and one parent or none. Sorry, I meant: __CLASS__ and get_class($this) They are both different things, and they can return different values. Like someone said it earlier, __CLASS__ is deterministic: you know its value at compile. get_class($this) is not : you cannot guess its value before run time. What do you mean by RELATIVE? I mean, when you want to go upwards, to reach an ancestor class. I think there is an ambiguity: for you, ::parent always means the parent of __CLASS__ But it could also mean: the parent of get_class($this), in the mind of a programmer. And under certain conditions, like the one I explained, you cannot use parent:: for that ; I must use a lot of get_class() and laborious turnarounds to get what I want. Baptiste -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
I mean, when you want to go upwards, to reach an ancestor class. You can't go upwards, because there's no upwards for classes. You can use the information you already have, via static:: and function that is analogous to it for static and get_parent_class for non-static. But it could also mean: the parent of get_class($this), in the mind of a programmer. Then you can use get_parent_class($this) I guess. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
With static:: you are not able to call method of parent with the same name. Ah, I see you point. I'm starting to dislike all this idea of let's have an object without really having an object... It's becoming messy now - we now need to start to invent all kinds of complex propagation rules for it in parallel with the true object propagation rules. Why not just have an object then? -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP-DEV] [patch] Late static bindings (LSB)
It's becoming messy now - we now need to start to invent all kinds of complex propagation rules for it in parallel with the true object propagation rules. Why not just have an object then? Because if you could only see the incredible number of get_class($this) and of if(__CLASS__!=get_class($this)) do this or that and of $t = get_parent_class($class); return ($t!=__CLASS__ ? $t : $class)' and other special unreadable hacks I have to imagine in order to get what I want. Like that one, ridiculous: static private function getStruct($class) { if(!(is_array(Entity::$struct) array_key_exists($class, Entity::$struct))) { eval(if(!isset(.$class.::\$structure)) self::array2xml('.$class.');); eval(Entity::\$struct[\$class] = new SimpleXMLElement( .$class.::\$structure);); } return Entity::$struct[$class]; } Do you understand what it does? Do you find it readable? Clean? I don't. Yet that's what I have to write in PHP. And when you have 20 methods in a class, 3 or 4 levels of inheritance, and you constantly have to manipulate get_parent_class($this) and other get_class($this) and other eval($class::..), it becomes impossible. There must be a cleaner way to express what you want to write. Maybe the problem arises in PHP because, as far as I know, there is no way to define a function as virtual, like in C++, and so you can't choose between static lookup or dynamic lookup. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP-DEV] [patch] Late static bindings (LSB)
So we have at least three different views on concept. It seems that patch will be delayed again. :( Thanks. Dmitry. -Original Message- From: Stanislav Malyshev [mailto:[EMAIL PROTECTED] Sent: Wednesday, September 19, 2007 8:51 PM To: Dmitry Stogov Cc: 'Marcus Boerger'; 'Lukas Kahwe Smith'; 'Michael Lively'; 'Etienne Kneuss'; internals@lists.php.net; 'Andi Gutmans' Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB) So to clarify the question... ?php class A { function foo() { return get_called_class(); } } class B extends A { function bar() { return A::foo(); } } class C extensa A { function bar() { return B::bar(); } } echo B::foo(); // this must return B. This is not a question, the question is in the following two lines... echo B::bar(); // this must return B, because B::bar() calls to A::foo() and A is parent of B, so late static binding still the same I don't understand this. How comes you called A::foo() and you get B? Doesn't make sense to me. If you call A::foo, you are supposed to get A. It looks like your intent is that A::foo() returns different things depending on where it is called, which is not good. echo C::bar(); // this must return B too, because C:bar() calls to B::bar(), but B is not the parent of C, so the call to B::bar() is handled in the same way as in the previous line. This should give the same as previous, of course, since in both cases B::bar() is called. Is this the expected behavior? (I would prefer it. My previous patches worked in this way). I don't think it's good. Or may be both lines must return A? (like Etienne's patches do, and like my latest path does) Yes. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP-DEV] [patch] Late static bindings (LSB)
From technical point of view it is possible to propagate LSB with self::, parent::, and static:: and not with CLASS::. I think it may be a good compromise. Thanks. Dmitry. -Original Message- From: Stefan Walk [mailto:[EMAIL PROTECTED] Sent: Thursday, September 20, 2007 1:10 PM To: Dmitry Stogov; internals@lists.php.net Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB) Is it possible or feasible to distinguish betwenn parent:: and NameOfParentClass::? That would allow to push a call up while preserving the called name while not making Class:: mean different things depending on the location of the call, which is a very bad thing IMO (it's an effect that may not be desired). Regards, Stefan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Is it possible or feasible to distinguish betwenn parent:: and NameOfParentClass::? That would allow to push a call up while preserving the called name while not making Class:: mean different things depending on the location of the call, which is a very bad thing IMO (it's an effect that may not be desired). Regards, Stefan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
So we have at least three different views on concept. It seems that patch will be delayed again. :( I think we better spend time on figuring out the concept and then do the patch than first do the patch and then discover we don't know how it was supposed to work :) -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Is it possible or feasible to distinguish betwenn parent:: and NameOfParentClass::? That would allow to push a call up while I'm not sure I understand - what's the difference? Can you give an example? -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Stanislav Malyshev wrote: So we have at least three different views on concept. It seems that patch will be delayed again. :( I think we better spend time on figuring out the concept and then do the patch than first do the patch and then discover we don't know how it was supposed to work :) How about writing the test cases first - and then the patch? -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
How about writing the test cases first - and then the patch? I'm fine with that - that's why I asking people for examples of what they want to do with it. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP-DEV] [patch] Late static bindings (LSB)
I hope I won't bother you with obvious things, but I think Stefan has pointed out something important about LSB: the importance of the relative access (like parent::), and the ambiguity of the context. It's not a problem of static data. Let me give an example, from my present real-life. I am writing an ORM in PHP, and I really need LSB. The principle is simple: to each table of the DB corresponds a class (a PHP class). One table = one class. One column = one attribute. All my PHP classes inherit from an abstract base class, who owns the main abstract methods (of access to the DB, like selects, inserts, etc). The structure of a table (which datatypes, keys, etc.) is represented through an XML string, in a static variable, in the corresponding PHP class. It is static because all the instances of a same class (= of a same table) share the same structure of course; but it could be defined as not static as well. Now, let's say the base class is called Entity. And let's say I have an inherited class called Client: Abstract Class Entity { function read() {} function delete() {} ... } Class Client extends Entity { public $id; public $first_name; public $last_name; static public $structure = ? structure of Client ?; } Now, imagine you are programming the delete function in class Entity. And you have to use the $structure variable. Since all the objects you are manipulating are Client objects (or other inherited table objects), it would be logical to write: parent::$structure and not: self::$structure, because Entity has no $structure variable. The structures belong to the table classes, not to Entity. But parent::$structure has no meaning at compilation time in Entity. There is no way for PHP to guess what you want to do: do you mean now, or do you mean at run time? Personally, I think one should give the programmer the choice, exactly like the programmer is given the choice between __CLASS__ (now, like it is written steadily in the code) and get_parent_class() (at run time, like objects are really instantiated). I may be wrong, but I think LSB occurs every time you need to do something in a RELATIVE way (get_parent_class(), parent::), because there is an ambiguity upon what you consider as your reference, when you write something like parent::$structure. There relies the problem; it's not a question of static or not static. The problem just frequently occurs with static variables. Anyway, I do agree with Stanislav when he writes I think we better spend time on figuring out the concept. And sorry for my commonplace prose. :) Baptiste Autin http://www.baptisteautin.com/ -Original Message- From: Stanislav Malyshev [mailto:[EMAIL PROTECTED] Sent: jeudi 20 septembre 2007 20:58 To: Zoe Slattery Cc: Dmitry Stogov; 'Marcus Boerger'; 'Lukas Kahwe Smith'; 'Michael Lively'; 'Etienne Kneuss'; internals@lists.php.net; 'Andi Gutmans' Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB) How about writing the test cases first - and then the patch? I'm fine with that - that's why I asking people for examples of what they want to do with it. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -Original Message- From: Stanislav Malyshev [mailto:[EMAIL PROTECTED] Sent: jeudi 20 septembre 2007 20:58 To: Zoe Slattery Cc: Dmitry Stogov; 'Marcus Boerger'; 'Lukas Kahwe Smith'; 'Michael Lively'; 'Etienne Kneuss'; internals@lists.php.net; 'Andi Gutmans' Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB) How about writing the test cases first - and then the patch? I'm fine with that - that's why I asking people for examples of what they want to do with it. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
From technical point of view it is possible to propagate LSB with self::, parent::, and static:: and not with CLASS::. I think it may be a good compromise. I am very much in favor of this. I think it allows the greatest amount of control. If you need a specific class's static method called then passing that class' name is the best idea. i would question wether it is a good idea to make self:: work like that though. Thanks. Dmitry. -Original Message- From: Stefan Walk [mailto:[EMAIL PROTECTED] Sent: Thursday, September 20, 2007 1:10 PM To: Dmitry Stogov; internals@lists.php.net Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB) Is it possible or feasible to distinguish betwenn parent:: and NameOfParentClass::? That would allow to push a call up while preserving the called name while not making Class:: mean different things depending on the location of the call, which is a very bad thing IMO (it's an effect that may not be desired). Regards, Stefan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- No virus found in this incoming message. Checked by AVG Free Edition. Version: 7.5.487 / Virus Database: 269.13.21/1010 - Release Date: 9/15/2007 7:54 PM -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Do you have any ideas on how to allow this to be at all useful with inheritance and overriding? If the patch is left to where these examples would all return 'A' and something wasn't put in place to allow overloading a static function AND forward on the original called class What do you mean by overloading a static function? What you are trying to do? I have explained this on list twice already...but here it goes again, maybe a slightly more concrete example will help: Say I have a class that is used to generate queries based on the values of certain static properties. ?php class TableSelectBuilder { static protected $tableName; static protected $tableColumns; static protected function buildSelectQuery() { return SELECT .implode(', ', static::$tableColumns). FROM .static::$tableName; } } class TestTableSelectBuilder extends TableSelectBuilder { static protected $tableName = 'test'; static protected $tableColumns = array('col1', 'col2', 'col3'); static public function test() { return self::buildSelectQuery(); } } echo TestTableQueryBuilder::test().\n; ? Running this script using the latest patch by Dmitry or Etienne will echo SELECT col1, col2, col3 FROM test. This is perfect, I love it. Now I want to extend TableSelectBuilder to prepend EXPLAIN to a query. I then want to change TestTableSelectBuilder to extend that class instead ?php class TableSelectBuilder { static protected $tableName; static protected $tableColumns; static protected function buildSelectQuery() { return SELECT .implode(', ', static::$tableColumns). FROM .static::$tableName; } } class TableSelectExplainBuilder extends TableSelectBuilder { static protected function buildSelectQuery() { return EXPLAIN .parent::buildSelectQuery(); } } class TestTableQueryBuilder extends TableSelectExplainBuilder { static protected $tableName = 'test'; static protected $tableColumns = array('col1', 'col2', 'col3'); static public function test() { return self::buildSelectQuery(); } } echo TestTableQueryBuilder::test().\n; ? This now echos EXPLAIN SELECT FROM. This is obviously not what is desired. Changing parent:: to static:: will cause a segfault due to infinite recursion as will self::. So in short there is absolutely no way to make TableSelectExplainBuilder useful in the current patch without duplicating the parent class code. This limitation is part of the problem that lsb is supposed to solve. to the parent class then usefulness of late static binding is php is going to be diminished. Usefulness for what? -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- No virus found in this incoming message. Checked by AVG Free Edition. Version: 7.5.487 / Virus Database: 269.13.21/1010 - Release Date: 9/15/2007 7:54 PM -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP-DEV] [patch] Late static bindings (LSB)
Hi Michael, Good catch. You can get the behavior that you expect by enabling (#ifdef ZEND_LSB2) in my patch. Tests lsb_018.phpt and lsb_019.phpt are especially for this behavior. I am not sure which behavior shouldbe in final patch. It seems like support for inheritance provides more flixebility, but makes concept harder to understand. Thanks. Dmitry. -Original Message- From: Michael Lively [mailto:[EMAIL PROTECTED] Sent: Wednesday, September 19, 2007 8:34 AM To: Dmitry Stogov; 'Etienne Kneuss' Cc: internals@lists.php.net; Stanislav Malyshev; Andi Gutmans Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB) There is a serious problem with both of these patches as they are now. I understand the principal behind ? class A { static public function test() { echo get_called_class() } } class B extend A { static public function test2() { A::test(); } } B::test2() ? Returning 'A'. But I don't think that it is wise making this change without providing a way to still allow LSB to work further down an inheritance structure. The whole purpose behind late static binding is to offer greater flexibility when dealing with inheritance of static functions. I understand that the aspect of the original patch returning 'B' for the code above is incorrect. However, consider the following scenario. ?php class A { static public function test() { echo get_called_class().\n; } } class B { static public function test() { // Performing additional needed tasks. parent::test(); } } ? In class B it is impossible to perform additional work in ::test() and allow class A to still do it's work while still being able to identify the class that originated the set of calls. I don't think it can be denied that this is incredibly inflexible and is somewhat against the reason for introducing late static binding. I think it is important that a solution is found to this problem, whether it is allowing parent:: to forward on the 'called class' or introducing a new keyword:: that will forward on the 'called class'. Also, just as a somewhat obvious side note I think the ability to do what I have mentioned will be expected by the OO programmers (which is who lsb is for): ?php class A { public function test() { echo get_class($this); } } class B extends A { public function test() { // Performing additional needed tasks. parent::test(); } } $b = new B(); $b-test(); ? Returns 'B' with no problem - Original Message - From: Dmitry Stogov [EMAIL PROTECTED] To: 'Etienne Kneuss' [EMAIL PROTECTED] Cc: internals@lists.php.net; Stanislav Malyshev [EMAIL PROTECTED]; Andi Gutmans [EMAIL PROTECTED] Sent: Tuesday, September 18, 2007 5:59 AM Subject: RE: [PHP-DEV] [patch] Late static bindings (LSB) Hi Etienne, At first thank you for catching the issue. I deside not to delay review of your patch and found only one serious bug. It doesn't handle nested calls (test lsb_017.phpt in my patch). --TEST-- ZE2 nested calls --FILE-- ?php class A { public static function test($x=null) { if (!is_null($x)) { echo $x\n; } return get_caller_class(); } } class B extends A { } class C extends A { } class D extends A { } echo A::test(B::test(C::test(D::test(.\n; ? ==DONE== --EXPECT-- D C B A ==DONE== Your patch outputs 4 D. BTW I like other aspects of your patch. I think your get_called_class() is better than my get_caller_class(). (I changed this in my new patch). I also made the same behavior that you maintained in private email. I didn't removed the corresponding code yet but wrapped it with #ifdef ZEND_LSB2. (tests lsb_018.phpt and test_019.phpt must be failed without it). I also made several optimizations. The latest version of my patch is attached. I think if you fix the bug that I maintained before our patches will near identical. BTW may be your patch will be better, so please make a mixture of our patches. I assume they have exactly the same behavior, so we need the fastest one. Thanks. Dmitry. -Original Message- From: Etienne Kneuss [mailto:[EMAIL PROTECTED] Sent: Sunday, September 16, 2007 8:18 PM To: Dmitry Stogov Cc: internals@lists.php.net Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB) Hello, I made the update anyway as it looked like it wouldn't take much time. Attached is a updated version of my patch, along with all the tests related to it: http://patches.colder.ch/Zend/late_static_bindings_take7.patch?markup -- Etienne Kneuss http://www.colder.ch Men never do evil so completely and cheerfully as when they do it from a religious conviction. -- Pascal
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Dmitry Stogov wrote: I am not sure which behavior shouldbe in final patch. It seems like support for inheritance provides more flixebility, but makes concept harder to understand. Well inheritance is an advanced OO concept. As such its something that requires a bit of getting into. But making it inconsistent will not help ease of use. regards, Lukas -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Hello Lukas, right, we already have inheritance all over so we should do it here as well. Nice work so far. marcus Wednesday, September 19, 2007, 9:07:16 AM, you wrote: Dmitry Stogov wrote: I am not sure which behavior shouldbe in final patch. It seems like support for inheritance provides more flixebility, but makes concept harder to understand. Well inheritance is an advanced OO concept. As such its something that requires a bit of getting into. But making it inconsistent will not help ease of use. regards, Lukas Best regards, Marcus -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP-DEV] [patch] Late static bindings (LSB)
So to clarify the question... ?php class A { function foo() { return get_called_class(); } } class B extends A { function bar() { return A::foo(); } } class C extensa A { function bar() { return B::bar(); } } echo B::foo(); // this must return B. This is not a question, the question is in the following two lines... echo B::bar(); // this must return B, because B::bar() calls to A::foo() and A is parent of B, so late static binding still the same echo C::bar(); // this must return B too, because C:bar() calls to B::bar(), but B is not the parent of C, so the call to B::bar() is handled in the same way as in the previous line. ? Is this the expected behavior? (I would prefer it. My previous patches worked in this way). Or may be both lines must return A? (like Etienne's patches do, and like my latest path does) Thanks. Dmitry. -Original Message- From: Marcus Boerger [mailto:[EMAIL PROTECTED] Sent: Wednesday, September 19, 2007 12:43 PM To: Lukas Kahwe Smith Cc: Dmitry Stogov; 'Michael Lively'; 'Etienne Kneuss'; internals@lists.php.net; 'Stanislav Malyshev'; 'Andi Gutmans' Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB) Hello Lukas, right, we already have inheritance all over so we should do it here as well. Nice work so far. marcus Wednesday, September 19, 2007, 9:07:16 AM, you wrote: Dmitry Stogov wrote: I am not sure which behavior shouldbe in final patch. It seems like support for inheritance provides more flixebility, but makes concept harder to understand. Well inheritance is an advanced OO concept. As such its something that requires a bit of getting into. But making it inconsistent will not help ease of use. regards, Lukas Best regards, Marcus -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
oh… I guess I see it somehow the third way class A { function foo() { return get_called_class(); } } class B extends A { function bar1() { return self::foo(); // it is called using inheritance-rules } function bar2() { return A::foo(); // it is called directly! } } echo B::bar1(); // B echo B::bar2(); // A On 9/19/07, Dmitry Stogov [EMAIL PROTECTED] wrote: So to clarify the question... ?php class A { function foo() { return get_called_class(); } } class B extends A { function bar() { return A::foo(); } } class C extensa A { function bar() { return B::bar(); } } echo B::foo(); // this must return B. This is not a question, the question is in the following two lines... echo B::bar(); // this must return B, because B::bar() calls to A::foo() and A is parent of B, so late static binding still the same echo C::bar(); // this must return B too, because C:bar() calls to B::bar(), but B is not the parent of C, so the call to B::bar() is handled in the same way as in the previous line. ? Is this the expected behavior? (I would prefer it. My previous patches worked in this way). Or may be both lines must return A? (like Etienne's patches do, and like my latest path does) Thanks. Dmitry. -- Alexey Zakhlestin http://blog.milkfarmsoft.com/
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Hello Dmitry, personally I'd argue with the stayed in same hierarchy. So all return B. macus Wednesday, September 19, 2007, 12:48:06 PM, you wrote: So to clarify the question... ?php class A { function foo() { return get_called_class(); } } class B extends A { function bar() { return A::foo(); } } class C extensa A { function bar() { return B::bar(); } } echo B::foo(); // this must return B. This is not a question, the question is in the following two lines... echo B::bar(); // this must return B, because B::bar() calls to A::foo() and A is parent of B, so late static binding still the same echo C::bar(); // this must return B too, because C:bar() calls to B::bar(), but B is not the parent of C, so the call to B::bar() is handled in the same way as in the previous line. ? Is this the expected behavior? (I would prefer it. My previous patches worked in this way). Or may be both lines must return A? (like Etienne's patches do, and like my latest path does) Thanks. Dmitry. -Original Message- From: Marcus Boerger [mailto:[EMAIL PROTECTED] Sent: Wednesday, September 19, 2007 12:43 PM To: Lukas Kahwe Smith Cc: Dmitry Stogov; 'Michael Lively'; 'Etienne Kneuss'; internals@lists.php.net; 'Stanislav Malyshev'; 'Andi Gutmans' Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB) Hello Lukas, right, we already have inheritance all over so we should do it here as well. Nice work so far. marcus Wednesday, September 19, 2007, 9:07:16 AM, you wrote: Dmitry Stogov wrote: I am not sure which behavior shouldbe in final patch. It seems like support for inheritance provides more flixebility, but makes concept harder to understand. Well inheritance is an advanced OO concept. As such its something that requires a bit of getting into. But making it inconsistent will not help ease of use. regards, Lukas Best regards, Marcus -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php Best regards, Marcus -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP-DEV] [patch] Late static bindings (LSB)
Do you like to make it work for self::foo() and/or static::foo(), but not for parent::foo() and NAME::foo()? From my point of view it is little bit inconsistent, but anyway thank you for idea. Dmitry. -Original Message- From: Alexey Zakhlestin [mailto:[EMAIL PROTECTED] Sent: Wednesday, September 19, 2007 3:26 PM To: Dmitry Stogov Cc: Marcus Boerger; Lukas Kahwe Smith; Michael Lively; Etienne Kneuss; internals@lists.php.net; Stanislav Malyshev; Andi Gutmans Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB) oh. I guess I see it somehow the third way class A { function foo() { return get_called_class(); } } class B extends A { function bar1() { return self::foo(); // it is called using inheritance-rules } function bar2() { return A::foo(); // it is called directly! } } echo B::bar1(); // B echo B::bar2(); // A On 9/19/07, Dmitry Stogov [EMAIL PROTECTED] wrote: So to clarify the question... ?php class A { function foo() { return get_called_class(); } } class B extends A { function bar() { return A::foo(); } } class C extensa A { function bar() { return B::bar(); } } echo B::foo(); // this must return B. This is not a question, the question is in the following two lines... echo B::bar(); // this must return B, because B::bar() calls to A::foo() and A is parent of B, so late static binding still the same echo C::bar(); // this must return B too, because C:bar() calls to B::bar(), but B is not the parent of C, so the call to B::bar() is handled in the same way as in the previous line. ? Is this the expected behavior? (I would prefer it. My previous patches worked in this way). Or may be both lines must return A? (like Etienne's patches do, and like my latest path does) Thanks. Dmitry. -- Alexey Zakhlestin http://blog.milkfarmsoft.com/ -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
So to clarify the question... ?php class A { function foo() { return get_called_class(); } } class B extends A { function bar() { return A::foo(); } } class C extensa A { function bar() { return B::bar(); } } echo B::foo(); // this must return B. This is not a question, the question is in the following two lines... echo B::bar(); // this must return B, because B::bar() calls to A::foo() and A is parent of B, so late static binding still the same I don't understand this. How comes you called A::foo() and you get B? Doesn't make sense to me. If you call A::foo, you are supposed to get A. It looks like your intent is that A::foo() returns different things depending on where it is called, which is not good. echo C::bar(); // this must return B too, because C:bar() calls to B::bar(), but B is not the parent of C, so the call to B::bar() is handled in the same way as in the previous line. This should give the same as previous, of course, since in both cases B::bar() is called. Is this the expected behavior? (I would prefer it. My previous patches worked in this way). I don't think it's good. Or may be both lines must return A? (like Etienne's patches do, and like my latest path does) Yes. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Or may be both lines must return A? (like Etienne's patches do, and like my latest path does) Yes. Do you have any ideas on how to allow this to be at all useful with inheritance and overriding? If the patch is left to where these examples would all return 'A' and something wasn't put in place to allow overloading a static function AND forward on the original called class to the parent class then usefulness of late static binding is php is going to be diminished. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- No virus found in this incoming message. Checked by AVG Free Edition. Version: 7.5.487 / Virus Database: 269.13.21/1010 - Release Date: 9/15/2007 7:54 PM -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Do you have any ideas on how to allow this to be at all useful with inheritance and overriding? If the patch is left to where these examples would all return 'A' and something wasn't put in place to allow overloading a static function AND forward on the original called class What do you mean by overloading a static function? What you are trying to do? to the parent class then usefulness of late static binding is php is going to be diminished. Usefulness for what? -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
There is a serious problem with both of these patches as they are now. I understand the principal behind ? class A { static public function test() { echo get_called_class() } } class B extend A { static public function test2() { A::test(); } } B::test2() ? Returning 'A'. But I don't think that it is wise making this change without providing a way to still allow LSB to work further down an inheritance structure. The whole purpose behind late static binding is to offer greater flexibility when dealing with inheritance of static functions. I understand that the aspect of the original patch returning 'B' for the code above is incorrect. However, consider the following scenario. ?php class A { static public function test() { echo get_called_class().\n; } } class B { static public function test() { // Performing additional needed tasks. parent::test(); } } ? In class B it is impossible to perform additional work in ::test() and allow class A to still do it's work while still being able to identify the class that originated the set of calls. I don't think it can be denied that this is incredibly inflexible and is somewhat against the reason for introducing late static binding. I think it is important that a solution is found to this problem, whether it is allowing parent:: to forward on the 'called class' or introducing a new keyword:: that will forward on the 'called class'. Also, just as a somewhat obvious side note I think the ability to do what I have mentioned will be expected by the OO programmers (which is who lsb is for): ?php class A { public function test() { echo get_class($this); } } class B extends A { public function test() { // Performing additional needed tasks. parent::test(); } } $b = new B(); $b-test(); ? Returns 'B' with no problem - Original Message - From: Dmitry Stogov [EMAIL PROTECTED] To: 'Etienne Kneuss' [EMAIL PROTECTED] Cc: internals@lists.php.net; Stanislav Malyshev [EMAIL PROTECTED]; Andi Gutmans [EMAIL PROTECTED] Sent: Tuesday, September 18, 2007 5:59 AM Subject: RE: [PHP-DEV] [patch] Late static bindings (LSB) Hi Etienne, At first thank you for catching the issue. I deside not to delay review of your patch and found only one serious bug. It doesn't handle nested calls (test lsb_017.phpt in my patch). --TEST-- ZE2 nested calls --FILE-- ?php class A { public static function test($x=null) { if (!is_null($x)) { echo $x\n; } return get_caller_class(); } } class B extends A { } class C extends A { } class D extends A { } echo A::test(B::test(C::test(D::test(.\n; ? ==DONE== --EXPECT-- D C B A ==DONE== Your patch outputs 4 D. BTW I like other aspects of your patch. I think your get_called_class() is better than my get_caller_class(). (I changed this in my new patch). I also made the same behavior that you maintained in private email. I didn't removed the corresponding code yet but wrapped it with #ifdef ZEND_LSB2. (tests lsb_018.phpt and test_019.phpt must be failed without it). I also made several optimizations. The latest version of my patch is attached. I think if you fix the bug that I maintained before our patches will near identical. BTW may be your patch will be better, so please make a mixture of our patches. I assume they have exactly the same behavior, so we need the fastest one. Thanks. Dmitry. -Original Message- From: Etienne Kneuss [mailto:[EMAIL PROTECTED] Sent: Sunday, September 16, 2007 8:18 PM To: Dmitry Stogov Cc: internals@lists.php.net Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB) Hello, I made the update anyway as it looked like it wouldn't take much time. Attached is a updated version of my patch, along with all the tests related to it: http://patches.colder.ch/Zend/late_static_bindings_take7.patch?markup -- Etienne Kneuss http://www.colder.ch Men never do evil so completely and cheerfully as when they do it from a religious conviction. -- Pascal -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php No virus found in this incoming message. Checked by AVG Free Edition. Version: 7.5.487 / Virus Database: 269.13.21/1010 - Release Date: 9/15/2007 7:54 PM -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Since the call A::foo() is completely defined and that no fall back occurs, I guess A is more expected as a result of this script. Your patch will return B. I discussed this matter quite heavily on #php.pecl and the expectations were also that A should get returned here. I think you are right, static:: is supposed to mean the context of the call, so if A::foo() is called then static means A. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Hi Dmitry, your patch fails with one test of mine. It may show a difference in the conception we have of LSB's usage, consider the following snip: --%- ?php class A { public static function foo() { static::who(); } public static function who() { echo __CLASS__.\n; } } class B extends A { public static function test() { A::foo(); } public static function who() { echo __CLASS__.\n; } } B::test(); --%- Since the call A::foo() is completely defined and that no fall back occurs, I guess A is more expected as a result of this script. Your patch will return B. I discussed this matter quite heavily on #php.pecl and the expectations were also that A should get returned here. Now if returning A is what we really want for PHP's LSB, I'm not sure whether it's easily doable with your patch. To bring my patch up to date with the latest functionalities like constants access through constant()/defined() and callbacks wouldn't require much work. But if my patch, which uses a slightly different approach (which seems to be simpler according to patch size), have no way to go in anyway, I'd like to know it before I start wasting time on it again. Thanks in advance. -- Etienne Kneuss http://www.colder.ch Men never do evil so completely and cheerfully as when they do it from a religious conviction. -- Pascal -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Hello, I made the update anyway as it looked like it wouldn't take much time. Attached is a updated version of my patch, along with all the tests related to it: http://patches.colder.ch/Zend/late_static_bindings_take7.patch?markup -- Etienne Kneuss http://www.colder.ch Men never do evil so completely and cheerfully as when they do it from a religious conviction. -- Pascal ? tests/classes/hooks_byref.phpt ? tests/classes/lsb Index: Zend/zend_API.c === RCS file: /repository/ZendEngine2/zend_API.c,v retrieving revision 1.443 diff -u -p -r1.443 zend_API.c --- Zend/zend_API.c 31 Aug 2007 12:36:00 - 1.443 +++ Zend/zend_API.c 16 Sep 2007 16:11:35 - @@ -2860,6 +2860,10 @@ ZEND_API zend_bool zend_is_callable_ex(z lcname_len == sizeof(parent)-1 ZEND_U_EQUAL(Z_TYPE_PP(obj), lcname, lcname_len, parent, sizeof(parent)-1)) { ce = EG(active_op_array)-scope-parent; + } else if (EG(active_op_array) EG(active_op_array)-scope + lcname_len == sizeof(static)-1 + ZEND_U_EQUAL(Z_TYPE_PP(obj), lcname, lcname_len, static, sizeof(static)-1)) { + ce = zend_fetch_class_lsb(EG(active_op_array)-scope TSRMLS_CC); } else if (zend_u_lookup_class(Z_TYPE_PP(obj), Z_UNIVAL_PP(obj), Z_UNILEN_PP(obj), pce TSRMLS_CC) == SUCCESS) { ce = *pce; } Index: Zend/zend_builtin_functions.c === RCS file: /repository/ZendEngine2/zend_builtin_functions.c,v retrieving revision 1.352 diff -u -p -r1.352 zend_builtin_functions.c --- Zend/zend_builtin_functions.c 11 Sep 2007 11:35:46 - 1.352 +++ Zend/zend_builtin_functions.c 16 Sep 2007 16:11:38 - @@ -44,6 +44,7 @@ static ZEND_FUNCTION(define); static ZEND_FUNCTION(defined); static ZEND_FUNCTION(get_class); static ZEND_FUNCTION(get_parent_class); +static ZEND_FUNCTION(get_called_class); static ZEND_FUNCTION(method_exists); static ZEND_FUNCTION(property_exists); static ZEND_FUNCTION(class_exists); @@ -104,6 +105,7 @@ static zend_function_entry builtin_funct ZEND_FE(defined,NULL) ZEND_FE(get_class, NULL) ZEND_FE(get_parent_class, NULL) + ZEND_FE(get_called_class, NULL) ZEND_FE(method_exists, NULL) ZEND_FE(property_exists,NULL) ZEND_FE(class_exists, NULL) @@ -658,6 +660,30 @@ ZEND_FUNCTION(get_parent_class) } /* }}} */ +/* {{{ proto string get_called_class() U + Retrieves the class name that were initially called. @see static:: */ +ZEND_FUNCTION(get_called_class) +{ + zend_class_entry *lsb_scope; + + if (ZEND_NUM_ARGS()) { + ZEND_WRONG_PARAM_COUNT(); + } + + if (!EG(scope)) { + RETURN_FALSE; + } + + lsb_scope = zend_fetch_class_lsb(EG(scope) TSRMLS_CC); + + if (lsb_scope) { + RETURN_TEXTL(lsb_scope-name, lsb_scope-name_length, 1); + } else { + RETURN_FALSE; + } +} +/* }}} */ + static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass) /* {{{ */ { zval **obj, **class_name; Index: Zend/zend_compile.c === RCS file: /repository/ZendEngine2/zend_compile.c,v retrieving revision 1.767 diff -u -p -r1.767 zend_compile.c --- Zend/zend_compile.c 5 Sep 2007 07:24:52 - 1.767 +++ Zend/zend_compile.c 16 Sep 2007 16:11:47 - @@ -1701,6 +1701,7 @@ void zend_do_fetch_class(znode *result, fetch_type = zend_get_class_fetch_type(Z_TYPE(class_name-u.constant), Z_UNIVAL(class_name-u.constant), Z_UNILEN(class_name-u.constant)); switch (fetch_type) { case ZEND_FETCH_CLASS_SELF: + case ZEND_FETCH_CLASS_LATE: case ZEND_FETCH_CLASS_PARENT: SET_UNUSED(opline-op2); opline-extended_value = fetch_type; @@ -3178,7 +3179,9 @@ void zend_do_begin_class_declaration(zno if ((lcname_len == sizeof(self)-1 ZEND_U_EQUAL(Z_TYPE(class_name-u.constant), lcname, lcname_len, self, sizeof(self)-1)) || - (lcname_len == sizeof(parent)-1 + (lcname_len == sizeof(static)-1 +ZEND_U_EQUAL(Z_TYPE(class_name-u.constant), lcname, lcname_len, static, sizeof(static)-1))
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Since the call A::foo() is completely defined and that no fall back occurs, I guess A is more expected as a result of this script. Your patch will return B. I discussed this matter quite heavily on #php.pecl and the expectations were also that A should get returned here. I've taken a look at this patch and for the most part I agree that your code SHOULD return 'A'. However, one thing that I think is very important is that you are able to somehow pass-thru who the caller is when dealing with inheritance. For instance: ?php class Foo { const TEST_CONST = 'foo'; public function test() { return static::TEST_CONST; } } class Bar extends Foo { const TEST_CONST = 'bar'; } echo Foo::test().\n; echo Bar::test().\n; ? This works as expected outputting: foo bar However, this concept becomes very inflexible when dealing with some aspects of inheritance. Consider a child class that needs to do additional work in its test() method and then called the parent test() method to do the normal work. ?php class Bar2 extends Foo { const TEST_CONST = 'bar2'; public function test() { //do class specific things //try to continue the function chain return parent::test(); } } ? This will also output 'foo'. While I agree that in this case this concept does make sense, I do think it is important for there to be a way to have this function return 'bar2'. The way that would most make sense to me and still somewhat follow the rules is to change the return to static::test(); However this causes a seg fault in your current patch. I will do a little more checking to see why you are segfaulting here. In either case without having some way to chain callers this is going to become a very annoying problem when utilizing inheritance with late static binding. -- Mike Lively http://www.ds-o.com -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
- Original Message - From: Etienne Kneuss [EMAIL PROTECTED] To: internals@lists.php.net Sent: Sunday, September 16, 2007 10:50 AM Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB) However this causes a seg fault in your current patch. I will do a little more checking to see why you are segfaulting here. That's an endless recursion, hence the segfault ;) Yah, quickly found that out after running gdb In either case without having some way to chain callers this is going to become a very annoying problem when utilizing inheritance with late static binding. I aggree that it could be a problem indeed, but you usually use LSB to avoid having to redeclare static functions in child classes, if you do anyway, LSB looses its interest. You of course wouldn't HAVE to redeclare the static function. Occasionally you just need to do a little extra in a child class and if this breaks lsb (or makes it innefective) with no work around (static::) then that would be no good. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Michael Lively wrote: Since the call A::foo() is completely defined and that no fall back occurs, I guess A is more expected as a result of this script. Your patch will return B. I discussed this matter quite heavily on #php.pecl and the expectations were also that A should get returned here. I've taken a look at this patch and for the most part I agree that your code SHOULD return 'A'. However, one thing that I think is very important is that you are able to somehow pass-thru who the caller is when dealing with inheritance. For instance: ?php class Foo { const TEST_CONST = 'foo'; public function test() { return static::TEST_CONST; } } class Bar extends Foo { const TEST_CONST = 'bar'; } echo Foo::test().\n; echo Bar::test().\n; ? This works as expected outputting: foo bar However, this concept becomes very inflexible when dealing with some aspects of inheritance. Consider a child class that needs to do additional work in its test() method and then called the parent test() method to do the normal work. ?php class Bar2 extends Foo { const TEST_CONST = 'bar2'; public function test() { //do class specific things //try to continue the function chain return parent::test(); } } ? This will also output 'foo'. While I agree that in this case this concept does make sense, I do think it is important for there to be a way to have this function return 'bar2'. The way that would most make sense to me and still somewhat follow the rules is to change the return to static::test(); However this causes a seg fault in your current patch. I will do a little more checking to see why you are segfaulting here. That's an endless recursion, hence the segfault ;) In either case without having some way to chain callers this is going to become a very annoying problem when utilizing inheritance with late static binding. I aggree that it could be a problem indeed, but you usually use LSB to avoid having to redeclare static functions in child classes, if you do anyway, LSB looses its interest. Regards -- Mike Lively http://www.ds-o.com -- Etienne Kneuss http://www.colder.ch Men never do evil so completely and cheerfully as when they do it from a religious conviction. -- Pascal -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP-DEV] [patch] Late static bindings (LSB)
Attached. Thanks. Dmitry. -Original Message- From: Etienne Kneuss [mailto:[EMAIL PROTECTED] Sent: Sunday, September 09, 2007 11:02 PM To: Dmitry Stogov Cc: internals@lists.php.net Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB) Hello, sorry for the late reply, I am on vacations these weeks and only have a sparse access to web. I was aware that my patch missed supports for callbacks, and let it that way on purpose as I planned to do some cleanup work on callbacks. It looks like you placed the work necessary to have LSB in a different place than mine, generating more occurences and hence a quite bigger patch size. I'd like to see what implications it has. Sadly, the patch you gave me is not easily patchable with the current HEAD, do you have an up to date version ? Thanks in advance Dmitry Stogov wrote: Hi Etienne, We already have patch for late static binding that is very similar to yours. If you have time, please compare them. From quick look I see that our patch more accurate (it supports constants and runtime function calls) Does our patch miss something that your patch does? Thanks. Dmitry. -Original Message- From: Etienne Kneuss [mailto:[EMAIL PROTECTED] Sent: Friday, August 24, 2007 5:19 PM To: internals@lists.php.net Subject: [PHP-DEV] [patch] Late static bindings (LSB) Hi internals, here is a patch that implements Late static bindinds in a way that minimizes the performance hits that were feared. There is no significant slowdown or memory usage increase when running Zend/bench.php, which I assume is a good enough bench for that kind of matter, as it involves a stupid amount of (recursive) function calls. You can also find the patch here: http://patches.colder.ch/Zend/late_static_bindings_take6.patch?markup Here is a document that describes its usage: http://colder.ch/news/08-24-2007/28/late-static-bindings-expl.html Regards, -- Etienne Kneuss http://www.colder.ch Men never do evil so completely and cheerfully as when they do it from a religious conviction. -- Pascal -- Etienne Kneuss http://www.colder.ch Men never do evil so completely and cheerfully as when they do it from a religious conviction. -- Pascal -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php Index: Zend/zend_API.c === RCS file: /repository/ZendEngine2/zend_API.c,v retrieving revision 1.443 diff -u -p -d -r1.443 zend_API.c --- Zend/zend_API.c 31 Aug 2007 12:36:00 - 1.443 +++ Zend/zend_API.c 10 Sep 2007 07:59:35 - @@ -2860,6 +2860,9 @@ ZEND_API zend_bool zend_is_callable_ex(z lcname_len == sizeof(parent)-1 ZEND_U_EQUAL(Z_TYPE_PP(obj), lcname, lcname_len, parent, sizeof(parent)-1)) { ce = EG(active_op_array)-scope-parent; + } else if (lcname_len == sizeof(static)-1 + ZEND_U_EQUAL(Z_TYPE_PP(obj), lcname, lcname_len, static, sizeof(static)-1)) { + ce = EG(caller_scope); } else if (zend_u_lookup_class(Z_TYPE_PP(obj), Z_UNIVAL_PP(obj), Z_UNILEN_PP(obj), pce TSRMLS_CC) == SUCCESS) { ce = *pce; } Index: Zend/zend_builtin_functions.c === RCS file: /repository/ZendEngine2/zend_builtin_functions.c,v retrieving revision 1.350 diff -u -p -d -r1.350 zend_builtin_functions.c --- Zend/zend_builtin_functions.c 30 Aug 2007 07:43:53 - 1.350 +++ Zend/zend_builtin_functions.c 10 Sep 2007 07:59:35 - @@ -43,6 +43,7 @@ static ZEND_FUNCTION(error_reporting); static ZEND_FUNCTION(define); static ZEND_FUNCTION(defined); static ZEND_FUNCTION(get_class); +static ZEND_FUNCTION(get_caller_class); static ZEND_FUNCTION(get_parent_class); static ZEND_FUNCTION(method_exists); static ZEND_FUNCTION(property_exists); @@ -103,6 +104,7 @@ static zend_function_entry builtin_funct ZEND_FE(define, NULL) ZEND_FE(defined,NULL) ZEND_FE(get_class, NULL) + ZEND_FE(get_caller_class, NULL) ZEND_FE(get_parent_class, NULL) ZEND_FE(method_exists, NULL) ZEND_FE(property_exists,NULL) @@ -614,6 +616,26 @@ ZEND_FUNCTION(get_class) } /* }}} */ +/* {{{ proto string get_caller_class() + Retrieves the class name
Re: [PHP-DEV] [patch] Late static bindings (LSB)
Hello, sorry for the late reply, I am on vacations these weeks and only have a sparse access to web. I was aware that my patch missed supports for callbacks, and let it that way on purpose as I planned to do some cleanup work on callbacks. It looks like you placed the work necessary to have LSB in a different place than mine, generating more occurences and hence a quite bigger patch size. I'd like to see what implications it has. Sadly, the patch you gave me is not easily patchable with the current HEAD, do you have an up to date version ? Thanks in advance Dmitry Stogov wrote: Hi Etienne, We already have patch for late static binding that is very similar to yours. If you have time, please compare them. From quick look I see that our patch more accurate (it supports constants and runtime function calls) Does our patch miss something that your patch does? Thanks. Dmitry. -Original Message- From: Etienne Kneuss [mailto:[EMAIL PROTECTED] Sent: Friday, August 24, 2007 5:19 PM To: internals@lists.php.net Subject: [PHP-DEV] [patch] Late static bindings (LSB) Hi internals, here is a patch that implements Late static bindinds in a way that minimizes the performance hits that were feared. There is no significant slowdown or memory usage increase when running Zend/bench.php, which I assume is a good enough bench for that kind of matter, as it involves a stupid amount of (recursive) function calls. You can also find the patch here: http://patches.colder.ch/Zend/late_static_bindings_take6.patch?markup Here is a document that describes its usage: http://colder.ch/news/08-24-2007/28/late-static-bindings-expl.html Regards, -- Etienne Kneuss http://www.colder.ch Men never do evil so completely and cheerfully as when they do it from a religious conviction. -- Pascal -- Etienne Kneuss http://www.colder.ch Men never do evil so completely and cheerfully as when they do it from a religious conviction. -- Pascal -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP-DEV] [patch] Late static bindings (LSB)
Hi Etienne, We already have patch for late static binding that is very similar to yours. If you have time, please compare them. From quick look I see that our patch more accurate (it supports constants and runtime function calls) Does our patch miss something that your patch does? Thanks. Dmitry. -Original Message- From: Etienne Kneuss [mailto:[EMAIL PROTECTED] Sent: Friday, August 24, 2007 5:19 PM To: internals@lists.php.net Subject: [PHP-DEV] [patch] Late static bindings (LSB) Hi internals, here is a patch that implements Late static bindinds in a way that minimizes the performance hits that were feared. There is no significant slowdown or memory usage increase when running Zend/bench.php, which I assume is a good enough bench for that kind of matter, as it involves a stupid amount of (recursive) function calls. You can also find the patch here: http://patches.colder.ch/Zend/late_static_bindings_take6.patch?markup Here is a document that describes its usage: http://colder.ch/news/08-24-2007/28/late-static-bindings-expl.html Regards, -- Etienne Kneuss http://www.colder.ch Men never do evil so completely and cheerfully as when they do it from a religious conviction. -- Pascal Index: Zend/zend_API.c === RCS file: /repository/ZendEngine2/zend_API.c,v retrieving revision 1.442 diff -u -p -d -r1.442 zend_API.c --- Zend/zend_API.c 20 Aug 2007 09:48:41 - 1.442 +++ Zend/zend_API.c 24 Aug 2007 16:50:13 - @@ -2836,6 +2836,9 @@ ZEND_API zend_bool zend_is_callable_ex(z lcname_len == sizeof(parent)-1 ZEND_U_EQUAL(Z_TYPE_PP(obj), lcname, lcname_len, parent, sizeof(parent)-1)) { ce = EG(active_op_array)-scope-parent; + } else if (lcname_len == sizeof(static)-1 + ZEND_U_EQUAL(Z_TYPE_PP(obj), lcname, lcname_len, static, sizeof(static)-1)) { + ce = EG(caller_scope); } else if (zend_u_lookup_class(Z_TYPE_PP(obj), Z_UNIVAL_PP(obj), Z_UNILEN_PP(obj), pce TSRMLS_CC) == SUCCESS) { ce = *pce; } Index: Zend/zend_builtin_functions.c === RCS file: /repository/ZendEngine2/zend_builtin_functions.c,v retrieving revision 1.349 diff -u -p -d -r1.349 zend_builtin_functions.c --- Zend/zend_builtin_functions.c 24 Aug 2007 13:50:52 - 1.349 +++ Zend/zend_builtin_functions.c 24 Aug 2007 16:50:13 - @@ -43,6 +43,7 @@ static ZEND_FUNCTION(error_reporting); static ZEND_FUNCTION(define); static ZEND_FUNCTION(defined); static ZEND_FUNCTION(get_class); +static ZEND_FUNCTION(get_caller_class); static ZEND_FUNCTION(get_parent_class); static ZEND_FUNCTION(method_exists); static ZEND_FUNCTION(property_exists); @@ -103,6 +104,7 @@ static zend_function_entry builtin_funct ZEND_FE(define, NULL) ZEND_FE(defined,NULL) ZEND_FE(get_class, NULL) + ZEND_FE(get_caller_class, NULL) ZEND_FE(get_parent_class, NULL) ZEND_FE(method_exists, NULL) ZEND_FE(property_exists,NULL) @@ -614,6 +616,26 @@ ZEND_FUNCTION(get_class) } /* }}} */ +/* {{{ proto string get_caller_class() + Retrieves the class name */ +ZEND_FUNCTION(get_caller_class) +{ + int dup; + + if (!ZEND_NUM_ARGS()) { + if (EG(caller_scope)) { + RETURN_TEXTL(EG(caller_scope)-name, EG(caller_scope)-name_length, 1); + } else { + zend_error(E_ERROR, get_caller_class() called from outside a class); + } + } else { + ZEND_WRONG_PARAM_COUNT(); + RETURN_FALSE; + } +} +/* }}} */ + + /* {{{ proto string get_parent_class([mixed object]) U Retrieves the parent class name for object or class or current scope. */ ZEND_FUNCTION(get_parent_class) Index: Zend/zend_compile.c === RCS file: /repository/ZendEngine2/zend_compile.c,v retrieving revision 1.765 diff -u -p -d -r1.765 zend_compile.c --- Zend/zend_compile.c 24 Aug 2007 13:50:52 - 1.765 +++ Zend/zend_compile.c 24 Aug 2007 16:50:13 - @@ -1702,6 +1702,7 @@ void zend_do_fetch_class(znode *result, switch (fetch_type) { case ZEND_FETCH_CLASS_SELF: case ZEND_FETCH_CLASS_PARENT: + case