|  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
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Bug Type:
From: bas at dmt-software dot nl
New email:
PHP Version: OS:


 [2019-01-16 15:44 UTC] bas at dmt-software dot nl
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();

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 (


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2019-01-16 15:52 UTC]
-Status: Open +Status: Verified
 [2019-01-16 15:52 UTC]
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]
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]
-Status: Verified +Status: Wont fix
 [2019-01-30 08:31 UTC]
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-2023 The PHP Group
All rights reserved.
Last updated: Tue Jan 31 14:03:57 2023 UTC