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 this is not your bug, you can add a comment by following this link.
If this is your bug, but 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

Add a Patch

Pull Requests

Add a Pull Request

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-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 18 15:01:28 2024 UTC