On constructors: BC Break and Class compiler Improvements

From: Date: Thu, 01 Apr 2010 18:55:43 +0000
Subject: On constructors: BC Break and Class compiler Improvements
Groups: php.internals 
Request: Send a blank email to internals+get-47711@lists.php.net to get a copy of this message
Hey Internals, In our work converting the Zend Framework library to namespaces, we came across some inconsistencies in constructor namings. Clearly, with namespace support making class names shorter, we come back full circle where some class names collide with reserved words, thus we are forced to become creative with class names: What was once: class Foo_Bar_Array {} would become (1 to 1 mapping): namespace Foo\Bar; class Array {} but must become namespace Foo\Bar; class ArrayBar {} (or ArrayObj, ArrayClass, etc) We can work around these limitations. With that in mind though, this is the bigger challenge we are faced with... The following seems, to me, to be a BC break with regards to notices and E_STRICT usage: namespace Foo\Bar; class Filter { public function __construct() { /* construct stuff */ } public function filter($value) { /* return filtered */ } } Produces: PHP Strict Standards: Redefining already defined constructor for class Zend\Filter\Filter in [snip file] on line [snip line] This worked in 5.2.x. This worked in 5.3.0. This stopped working in 5.3.1 Moreover, I do think that this is NOT the correct behavior. While I know somewhere in the history of PHP we had an engine that preferred class names as constructor names, but thankfully- those days (one could only hope) are gone. IMO, the engine should be backwards compatible as best as possbile in the 5.x series and should (with the respect of PHP4 tendencies), reward programmers using proper PHP5 constructs, like __construct. (While I hate to use the english language as a crutch for the argument.. PHP is after all written in english, ... it is considered a best practice do have class names as nouns and methods as verbs. Since there are a lot of cases where the same words are both the noun and verb.. the verb being the method being acted on in the class, the noun - combined with the shorter class names due to namespaces, I can see this becoming a bigger problem as more people embrace namespaces.) Furthermore, static functions of the same name should not be marked as constructors by the engine in any situation (is there some BC we are keeping here? b/c I cannot see the use case.) Attached is a patch that fixes this behavior (against PHP_5_3). What it does: * If __construct is declared before a method of the same name as the class, you WILL NOT get a notice * If a method of the same name as the class appears before __construct(), you WILL get a notice, as the current behavior. (The idea here is that if you define __construct before anything else, as most people do, it will take priority and allow you to use the method name of the class name below that as normal) * Static methods of the same name as the class will NOT be marked as constructors (they currently are). This might invalidate the check done inside zend_do_end_class_declaration() that checks to see if the constructor is static. (Perhaps that first check becomes dead code?) I am not sure where the current behavior came from. I looks like it got merged into 5_2_x but then backed out and merged into 5_3_x somewhere along the line after 5.3.0 was released. In any case, considering we are not gonna get a context aware parser that will allow us to use reserved words for symbols like classes and functions, it would be nice to not have this seemingly artificial limitation on having method names that do not match the class name. Thanks, Ralph Schindler References: http://bugs.php.net/bug.php?id=35634 http://bugs.php.net/bug.php?id=48215

« previous php.internals (#47711) next »