Old style constructors in PHP-8

php.internals

Dmitry Stogov

7 years ago
Hi, I've just noticed that Wordpress-4.1 on PHP master started silently produce different output. The problem that PHP master started to ignore old-style constructors. They were deprecated in PHP-7 and PHP produced the following warning Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; ... has a deprecated constructor PHP master doesn't produce any warnings and just constructs a class without constructor. This silent behavior change may become a problem for porting legacy code to PHP-8, May be, it makes sense to emit fatal error in case of old-style constructor. Thanks. Dmitry.

Pierre Joye

7 years ago
On Wed, Jan 30, 2019, 6:11 PM Dmitry Stogov <dmitry@zend.com wrote:
> to PHP-8, > > May be, it makes sense to emit fatal error in case of old-style > constructor. >
Absolutely yes. It will be painless then to find them and fix accordingly. Once officially done, I am sure someone will write code converters as well.

Sebastian Bergmann

7 years ago
Am 30.01.2019 um 12:15 schrieb Pierre Joye:
> Once officially done, I am sure someone will write code converters as well.
The no_php4_constructor fixer of php-cs-fixer has been able to automatically migrate old-style constructors for years.

Pierre Joye

7 years ago
On Wed, Jan 30, 2019, 6:39 PM Sebastian Bergmann <sebastian@php.net wrote:
> Am 30.01.2019 um 12:15 schrieb Pierre Joye: > > Once officially done, I am sure someone will write code converters as > well. > > The no_php4_constructor fixer of php-cs-fixer has been able to > automatically migrate old-style constructors for years. >
even better then :)

Nikita Popov

7 years ago
On Wed, Jan 30, 2019 at 12:11 PM Dmitry Stogov <dmitry@zend.com> wrote:
> Hi, > > > I've just noticed that Wordpress-4.1 on PHP master started silently > produce different output. > > The problem that PHP master started to ignore old-style constructors. > > They were deprecated in PHP-7 and PHP produced the following warning > > > Deprecated: Methods with the same name as their class will not be > constructors in a future version of PHP; ... has a deprecated constructor > > > PHP master doesn't produce any warnings and just constructs a class > without constructor. > > This silent behavior change may become a problem for porting legacy code > to PHP-8, > > May be, it makes sense to emit fatal error in case of old-style > constructor. > > > Thanks. Dmitry. >
First of all, it is probably important to note that the RFC for this ( https://wiki.php.net/rfc/remove_php4_constructors) explicitly specifies that in PHP 8 methods with the same name as the class are interpreted as ordinary methods and no warning or error is thrown. I've CC'd Levi and Andrea, who authored this RFC. I think as an end goal, what the RFC specifies is preferable for a number of reasons: * You should be able to call your methods whatever you like. PHP only reserves the __ prefix for itself. * The behavior is consistent with classes inside namespaces, where methods with the same name as the class are treated as normal methods for a long time already. * The fact that a method has the same name as the class may be completely incidental if it comes from a trait (see https://bugs.php.net/bug.php?id=77470). The trait does not control in which classes it may be used and which names those classes may have. Of course, porting of legacy code is a legitimate concern. I think the relevant question in that regard is: How likely is it that people will port code directly from PHP 5 to PHP 8, without ever running it on PHP 7, where this generates deprecation notices? Not very, I think. Finally, it should be mentioned that finding old style constructors is trivial with static analysis, and I believe that a lot of code style checker and analyzers already support this functionality since the release of PHP 7.0. Nikita

Larry Garfield

7 years ago
On Wednesday, January 30, 2019 5:41:45 AM CST Nikita Popov wrote:
> On Wed, Jan 30, 2019 at 12:11 PM Dmitry Stogov <dmitry@zend.com> wrote: > > Hi, > > > > > > I've just noticed that Wordpress-4.1 on PHP master started silently > > produce different output. > > > > The problem that PHP master started to ignore old-style constructors. > > > > They were deprecated in PHP-7 and PHP produced the following warning > > > > > > Deprecated: Methods with the same name as their class will not be > > constructors in a future version of PHP; ... has a deprecated constructor > > > > > > PHP master doesn't produce any warnings and just constructs a class > > without constructor. > > > > This silent behavior change may become a problem for porting legacy code > > to PHP-8, > > > > May be, it makes sense to emit fatal error in case of old-style > > constructor. > > > > > > Thanks. Dmitry. > > First of all, it is probably important to note that the RFC for this ( > https://wiki.php.net/rfc/remove_php4_constructors) explicitly specifies > that in PHP 8 methods with the same name as the class are interpreted as > ordinary methods and no warning or error is thrown. I've CC'd Levi and > Andrea, who authored this RFC. > > I think as an end goal, what the RFC specifies is preferable for a number > of reasons: > > * You should be able to call your methods whatever you like. PHP only > reserves the __ prefix for itself. > * The behavior is consistent with classes inside namespaces, where methods > with the same name as the class are treated as normal methods for a long > time already. > * The fact that a method has the same name as the class may be completely > incidental if it comes from a trait (see > https://bugs.php.net/bug.php?id=77470). The trait does not control in which > classes it may be used and which names those classes may have.
Every Drupal 7 or 8 site includes classes that have a method name the same as the class name, on the assumption that it's safe to do for a normal method in current PHP versions. Making that suddenly a Fatal would be, er, bad. :-) As others have noted, this is easily solved with static analysis tools. There's been discussion of WP moving to a PHP 7-based version of PHP sometime this year (no promises, but that's the scuttlebutt), which would let them convert to __construct() universally and safely well before PHP 8 becomes an issue. --Larry Garfield

Andreas Heigl

7 years ago
Am Mittwoch, den 30.01.2019, 09:30 -0600 schrieb Larry Garfield:
> On Wednesday, January 30, 2019 5:41:45 AM CST Nikita Popov wrote: > > On Wed, Jan 30, 2019 at 12:11 PM Dmitry Stogov <dmitry@zend.com> > > wrote: > > > Hi, > > > > > > > > > I've just noticed that Wordpress-4.1 on PHP master started > > > silently > > > produce different output. > > > > > > The problem that PHP master started to ignore old-style > > > constructors. > > > > > > They were deprecated in PHP-7 and PHP produced the following > > > warning > > > > > > > > > Deprecated: Methods with the same name as their class will not be > > > constructors in a future version of PHP; ... has a deprecated > > > constructor > > > > > > > > > PHP master doesn't produce any warnings and just constructs a > > > class > > > without constructor. > > > > > > This silent behavior change may become a problem for porting > > > legacy code > > > to PHP-8, > > > > > > May be, it makes sense to emit fatal error in case of old-style > > > constructor. > > > > > > > > > Thanks. Dmitry. > > > > First of all, it is probably important to note that the RFC for > > this ( > > https://wiki.php.net/rfc/remove_php4_constructors) explicitly > > specifies > > that in PHP 8 methods with the same name as the class are > > interpreted as > > ordinary methods and no warning or error is thrown. I've CC'd Levi > > and > > Andrea, who authored this RFC. > > > > I think as an end goal, what the RFC specifies is preferable for a > > number > > of reasons: > > > > * You should be able to call your methods whatever you like. PHP > > only > > reserves the __ prefix for itself. > > * The behavior is consistent with classes inside namespaces, where > > methods > > with the same name as the class are treated as normal methods for a > > long > > time already. > > * The fact that a method has the same name as the class may be > > completely > > incidental if it comes from a trait (see > > https://bugs.php.net/bug.php?id=77470). The trait does not control > > in which > > classes it may be used and which names those classes may have. > > Every Drupal 7 or 8 site includes classes that have a method name the > same as > the class name, on the assumption that it's safe to do for a normal > method in > current PHP versions. Making that suddenly a Fatal would be, er, > bad. :-) > > As others have noted, this is easily solved with static analysis > tools. > There's been discussion of WP moving to a PHP 7-based version of PHP > sometime > this year (no promises, but that's the scuttlebutt), which would let > them > convert to __construct() universally and safely well before PHP 8 > becomes an > issue.
AFAIK WP requires PHP5 already as the minimum PHP-Version. And AFAIK __construct worked with that as well. So there should be no need to wait for PHP7 readiness in WordPress to tackle this issue. Replacing the function-name-as-class-name constructors with __construct should be possible without a BC-break already. Even with PHP 5.0 as a min-requirement. Or am I missing something? Cheers Andreas ,,, (o o) +-------- -------------------------------------------------ooO-(_)-Ooo-+ | Andreas Heigl | | mailto: andreas@heigl.org N 50°22'59.5" E 08°23'58" | | http://andreas.heigl.org http://hei.gl/wiFKy7 | +- --------------------------------------------------------------------+ | http://hei.gl/root-ca | +- --------------------------------------------------------------------+

Nikita Popov

7 years ago
On Wed, Jan 30, 2019 at 4:38 PM Andreas Heigl <andreas@heigl.org> wrote:
> > > Am Mittwoch, den 30.01.2019, 09:30 -0600 schrieb Larry Garfield: > > On Wednesday, January 30, 2019 5:41:45 AM CST Nikita Popov wrote: > > > On Wed, Jan 30, 2019 at 12:11 PM Dmitry Stogov <dmitry@zend.com> > > > wrote: > > > > Hi, > > > > > > > > > > > > I've just noticed that Wordpress-4.1 on PHP master started > > > > silently > > > > produce different output. > > > > > > > > The problem that PHP master started to ignore old-style > > > > constructors. > > > > > > > > They were deprecated in PHP-7 and PHP produced the following > > > > warning > > > > > > > > > > > > Deprecated: Methods with the same name as their class will not be > > > > constructors in a future version of PHP; ... has a deprecated > > > > constructor > > > > > > > > > > > > PHP master doesn't produce any warnings and just constructs a > > > > class > > > > without constructor. > > > > > > > > This silent behavior change may become a problem for porting > > > > legacy code > > > > to PHP-8, > > > > > > > > May be, it makes sense to emit fatal error in case of old-style > > > > constructor. > > > > > > > > > > > > Thanks. Dmitry. > > > > > > First of all, it is probably important to note that the RFC for > > > this ( > > > https://wiki.php.net/rfc/remove_php4_constructors) explicitly > > > specifies > > > that in PHP 8 methods with the same name as the class are > > > interpreted as > > > ordinary methods and no warning or error is thrown. I've CC'd Levi > > > and > > > Andrea, who authored this RFC. > > > > > > I think as an end goal, what the RFC specifies is preferable for a > > > number > > > of reasons: > > > > > > * You should be able to call your methods whatever you like. PHP > > > only > > > reserves the __ prefix for itself. > > > * The behavior is consistent with classes inside namespaces, where > > > methods > > > with the same name as the class are treated as normal methods for a > > > long > > > time already. > > > * The fact that a method has the same name as the class may be > > > completely > > > incidental if it comes from a trait (see > > > https://bugs.php.net/bug.php?id=77470). The trait does not control > > > in which > > > classes it may be used and which names those classes may have. > > > > Every Drupal 7 or 8 site includes classes that have a method name the > > same as > > the class name, on the assumption that it's safe to do for a normal > > method in > > current PHP versions. Making that suddenly a Fatal would be, er, > > bad. :-) > > > > As others have noted, this is easily solved with static analysis > > tools. > > There's been discussion of WP moving to a PHP 7-based version of PHP > > sometime > > this year (no promises, but that's the scuttlebutt), which would let > > them > > convert to __construct() universally and safely well before PHP 8 > > becomes an > > issue. > > AFAIK WP requires PHP5 already as the minimum PHP-Version. And AFAIK > __construct worked with that as well. So there should be no need to > wait for PHP7 readiness in WordPress to tackle this issue. > > Replacing the function-name-as-class-name constructors with __construct > should be possible without a BC-break already. Even with PHP 5.0 as a > min-requirement. > > Or am I missing something? >
That's correct. The standard pattern is to do something like this: class Foobar { public function __construct($args) { ... } public function Foobar($args) { $this->__construct($args); } } This ensures BC even for cases where people are explicitly calling Foobar::Foobar() for some reason (e.g. because they don't know that parent::__construct() can be used even if the parent constructor is not named __construct). WordPress does use this pattern for their constructors. The original problem that Dmitry ran into is that WordPress 4.1 was released one year before PHP 7, so they obviously didn't do this constructor migration at that point in time yet. Nikita