PHP Bug 48215
| From: | Scott MacVicar | Date: | Wed, 17 Jun 2009 15:43:52 +0000 |
| Subject: | PHP Bug 48215 | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-44346@lists.php.net to get a copy of this message | ||
Hey,
Bug 48215 was a BC break from the previous 5.2 behaviour, it stemmed from a change for bug #39127.
class a { function a($arg='') { echo $arg; } }
class b extends a {}
$b = new b;
$b->b('foo');
$b->__construct('foo');
This prints out an error in 5.3 which is fine, the unexpected change was that if a __construct() method was actually defined as well as a method that matched the class name it would alias the parent method to the constructor. The test is attached in the patch.
Just sending off to internals first since we're so late in the RC stage.
Scott
Index: tests/bug48215.phpt =================================================================== RCS file: tests/bug48215.phpt diff -N tests/bug48215.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ tests/bug48215.phpt 17 Jun 2009 15:37:26 -0000 @@ -0,0 +1,38 @@ +--TEST-- +Bug #48215 - parent::method() calls __construct +--FILE-- +<?php +class A +{ + public function __construct() { + echo __METHOD__ . "\n"; + } + protected function A() + { + echo __METHOD__ . "\n"; + } +} +class B extends A +{ + public function __construct() { + echo __METHOD__ . "\n"; + parent::__construct(); + } + public function A() + { + echo __METHOD__ . "\n"; + parent::A(); + } +} +$b = new B(); +$b->A(); +?> +===DONE=== +--EXPECTF-- + +Strict Standards: Redefining already defined constructor for class A in %s on line %d +B::__construct +A::__construct +B::A +A::A +===DONE=== Index: zend_object_handlers.c =================================================================== RCS file: /repository/ZendEngine2/zend_object_handlers.c,v retrieving revision 1.135.2.6.2.22.2.29 diff -u -r1.135.2.6.2.22.2.29 zend_object_handlers.c --- zend_object_handlers.c 12 Jun 2009 21:36:53 -0000 1.135.2.6.2.22.2.29 +++ zend_object_handlers.c 17 Jun 2009 15:37:26 -0000 @@ -28,6 +28,7 @@ #include "zend_object_handlers.h" #include "zend_interfaces.h" #include "zend_closures.h" +#include "zend_compile.h" #define DEBUG_OBJECT_HANDLERS 0 @@ -941,7 +942,8 @@ if (function_name_strlen == ce->name_length && ce->constructor) { lc_class_name = zend_str_tolower_dup(ce->name, ce->name_length); - if (!memcmp(lc_class_name, function_name_strval, function_name_strlen)) { + /* Only change the method to the constructor if a __construct() method doesn't exist */ + if (!memcmp(lc_class_name, function_name_strval, function_name_strlen) && memcmp(ce->constructor->common.function_name, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME))) { fbc = ce->constructor; } efree(lc_class_name);
Index: tests/bug48215.phpt =================================================================== RCS file: tests/bug48215.phpt diff -N tests/bug48215.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ tests/bug48215.phpt 17 Jun 2009 15:37:26 -0000 @@ -0,0 +1,38 @@ +--TEST-- +Bug #48215 - parent::method() calls __construct +--FILE-- +<?php +class A +{ + public function __construct() { + echo __METHOD__ . "\n"; + } + protected function A() + { + echo __METHOD__ . "\n"; + } +} +class B extends A +{ + public function __construct() { + echo __METHOD__ . "\n"; + parent::__construct(); + } + public function A() + { + echo __METHOD__ . "\n"; + parent::A(); + } +} +$b = new B(); +$b->A(); +?> +===DONE=== +--EXPECTF-- + +Strict Standards: Redefining already defined constructor for class A in %s on line %d +B::__construct +A::__construct +B::A +A::A +===DONE=== Index: zend_object_handlers.c =================================================================== RCS file: /repository/ZendEngine2/zend_object_handlers.c,v retrieving revision 1.135.2.6.2.22.2.29 diff -u -r1.135.2.6.2.22.2.29 zend_object_handlers.c --- zend_object_handlers.c 12 Jun 2009 21:36:53 -0000 1.135.2.6.2.22.2.29 +++ zend_object_handlers.c 17 Jun 2009 15:37:26 -0000 @@ -28,6 +28,7 @@ #include "zend_object_handlers.h" #include "zend_interfaces.h" #include "zend_closures.h" +#include "zend_compile.h" #define DEBUG_OBJECT_HANDLERS 0 @@ -941,7 +942,8 @@ if (function_name_strlen == ce->name_length && ce->constructor) { lc_class_name = zend_str_tolower_dup(ce->name, ce->name_length); - if (!memcmp(lc_class_name, function_name_strval, function_name_strlen)) { + /* Only change the method to the constructor if a __construct() method doesn't exist */ + if (!memcmp(lc_class_name, function_name_strval, function_name_strlen) && memcmp(ce->constructor->common.function_name, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME))) { fbc = ce->constructor; } efree(lc_class_name);