php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77470 Methods in traits can unwillingly function as constructor
Submitted: 2019-01-16 15:44 UTC Modified: 2019-01-30 09:58 UTC
From: bas at dmt-software dot nl Assigned:
Status: Wont fix Package: Class/Object related
PHP Version: Irrelevant OS:
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: bas at dmt-software dot nl
New email:
PHP Version: OS:

 

 [2019-01-16 15:44 UTC] bas at dmt-software dot nl
Description:
------------
A class without __construct method cannot use a trait that has a method that equals the class it's name. It will execute the trait method as constructor when E_DEPRECATED errors are ignored. This should never happen.




Test script:
---------------
error_reporting(E_ALL ^ E_DEPRECATED);

class Callback {
    use CallbackTrait;
}

trait CallbackTrait {
    public function callback() {
        echo 'this is called';
    }
}

new Callback();
--- 
https://3v4l.org/CWBai

Expected result:
----------------
It should ignore the method as constructor like extends does or it should trigger a fatal error as it does when a constructor is present (https://3v4l.org/nbh6X)


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-01-16 15:52 UTC] nikic@php.net
-Status: Open +Status: Verified
 [2019-01-16 15:52 UTC] nikic@php.net
I agree that we should only treat __construct as a constructor when coming from a trait.

Interesting that this only comes up now, probably not many people using traits with non-namespaced code.
 [2019-01-25 10:36 UTC] nikic@php.net
While trying to fix this I found bug #55554, which is where the current behavior was implemented.

It also has this example, which makes slightly more sense in that the legacy ctor name is used as an explicit alias:

trait TConstructor {
    public function constructor() {
        echo "ctor executed\n";
    }
}
class NewConstructor {
    use TConstructor {
        constructor as __construct;
    }
}
class LegacyConstructor {
    use TConstructor {
        constructor as LegacyConstructor;
    }
}

Given this, I'm not sure whether to make this change. It would only be able to go into 7.4 if at all, and in PHP 8 legacy constructors are going away entirely, so the problem will resolve itself at that time.
 [2019-01-30 08:31 UTC] nikic@php.net
-Status: Verified +Status: Wont fix
 [2019-01-30 08:31 UTC] nikic@php.net
Marking this as won't fix per the above comment. Legacy dtor support is gone from PHP 8 and the code behaves as desired there. I don't think it's worthwhile to make a (BC-breaking) change in 7.4 in addition to that.
 [2019-01-30 09:58 UTC] bas at dmt-software dot nl
I agree. Thanks for looking into this.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Tue Apr 29 18:01:28 2025 UTC