php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77424 Classname length affects constructor inheritance from trait
Submitted: 2019-01-07 14:52 UTC Modified: 2019-01-07 22:52 UTC
From: tom at inflatablecookie dot com Assigned: cmb (profile)
Status: Duplicate Package: Scripting Engine problem
PHP Version: 7.3.0 OS: Mac OS Mojave
Private report: No CVE-ID: None
 [2019-01-07 14:52 UTC] tom at inflatablecookie dot com
Description:
------------
This is a -very- odd one..

Inheriting a __construct method from a trait in an implementing class does not work correctly if the fully qualified name of the class is of a certain combination of namespace and classname length - apparently 11 characters total. When applied, if the class is inspected via Reflection, the __construct method appears in the method list, however it is not considered a constructor by isConstructor(), and is not called on object instantiation.

Disabling OpCache does not appear to have any effect on the issue. I'm running the stock homebrew packaged version of PHP 7.3.0 on Mac OS Mojave - a few PECL extensions have been added to the installation, though disabling all of them makes no difference to the issue.





Test script:
---------------
<?php

namespace ab\abc {
    class Abc { use test; }
    class Abcd { use test; }

    trait test {
        public function __construct() { 
            echo '__construct '.get_class($this)."\n"; 
        }
    }

    new Abc();
    new Abcd();
}

Expected result:
----------------
Console output should be:

> __construct ab\abc\Abc
> __construct ab\abc\Abcd

Actual result:
--------------
> __construct ab\abc\Abc


Only the first line is echoed, the constructor for Abcd is never called (order of instantiation of the two classes is irrelevant).

Changing the namespace to "abc\abcd" for example however fixes the issue and both lines are echoed.
The name of the trait does not appear to have any effect. The characters used in namespace or classname do not matter, only the combined length.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-01-07 14:56 UTC] danack@php.net
This is quite possibly the same issue as https://bugs.php.net/bug.php?id=77291

The good news is that if it is, then it has been fixed in master. 

Would it be possible for you to test against the current master?
 [2019-01-07 16:26 UTC] tom at inflatablecookie dot com
Ah sorry, completely missed that one.

I've just compiled master and the test script appears to work as expected - it does seem to have been fixed.

I would just make a note however that the description of the offending change in the thread you linked to doesn't completely directly correspond to the behaviour I was seeing:

> "This regression has been introduced with commit 43aca31[1].  It is not particularly related to namespaces, and does not only affect __isset(), but rather all magic methods which are inherited from a trait, whose name has the same length as the class name, see, for instance, <https://3v4l.org/0jmp1>."

- Importantly, the length of the namespace *did* have a direct impact on whether this bug took effect. It may well be irrelevant now though.
 [2019-01-07 22:52 UTC] cmb@php.net
-Status: Open +Status: Duplicate -Assigned To: +Assigned To: cmb
 [2019-01-07 22:52 UTC] cmb@php.net
To clarify: the length of the class name is supposed to mean the
resolved class name as would be provided by the magic ::class
constant; in this case this would be string(11) "ab\abc\Abcd".

Closing as duplicate of bug #77291.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 15:01:29 2024 UTC