Anyone know of a PHP Magic Constant for Trait'

2019-05-16 09:26发布

问题:

To make it simple, I have noticed that PHP doesn't seem to offer any magic constant for determining what the name that a trait has been changed to in a class. Since this sounds confusing to me in words, I will give an example, as it is rather easy and would expect it to be somewhere in the new PHP 5.5, I don't see a way to doing it. So here it is:

Say we have some class, that uses some trait that conflicts with some function inside the class, example:

class SomeClass {
    use \Name\Space\SomeTrait    { SomeFunction as private NewFunctionName; }

    function SomeFunction() {
        $this->NewFunctionName();
    }
}

Since, obviously this class has the "SomeFunction" function, and we are aware that inside of SomeTrait we have included, is a function that is matching by name to a function we have inside this class. Now, since the "SomeFunction" came into this class via a trait inside of a \Name\Space, these 2 functions do 2 different things, but happen to use the same name, and inside of either another function or literally our 'SomeFunction', we then use the "SomeFunction" from our trait, by calling it by the "NewFunctionName".

So hopefully I haven't lost anyone here, as here is what my question comes down to in the above scenario. Within the \Name\Space\SomeTrait\SomeFunction(), how could one get the "NewFunctionName" that this trait function was assigned too? One would think to use a magic method, such as __FUNCTION__, or __METHOD__, or even __TRAIT__, except none of these give the expected result, so does anyone know a way to get this information without passing it to the function as a parameter and resulting in a hacky code? Maybe PHP 5.6 needs to add a new Magic Constant __AS__, or adjust the result of __TRAIT__, I dont understand why __TRAIT__ and __FUNCTION_ need to return the same information (or nearly the same information). Any help would be awesome, if it is an unconventional hacky method, Im interested in seeing my options, until I can open up a bug report with php regarding this. (if it is truly a bug)

edit:

My current, least hacky, method seems to be,

 debug_backtrace()[0]['function']

and though it works, I feel it is doing a lot to get a simple string, especially if you use the function a lot. :/

回答1:

This is the solution I ended up using. It's not very good but probably better than using the debug_backtrace function.

Problem example:

Trait ExampleTrait {
    protected function doSomethingRecursive() {
        // this is a problem because it could be renamed
        $this->doSomethingRecursive(); 
    }
}

Solution example:

Trait ExampleTrait {

    protected function doSomethingRecursive() {
        // this is a problem because it could be renamed
        $this->__internal_doSomethingRecursive(); 
    }

    private function __internal_doSomethingRecursive() {
        // this works because the class would have 
        // used and renamed the above function 
        // but this "internal" function *should*
        // remain available under it's original name
        $this->__internal_doSomethingRecursive(); 
    }

}

Of course it's possible to break this but for most cases it should be fine. You could also include the name of the trait in the internal function name to further prevent conflicts.



回答2:

Your current solution is going to be the best, with a couple tweaks:

debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS,1)[0]['function']

The DEBUG_BACKTRACE_IGNORE_ARGS and the frame limit of 1 there will make the backtrace shallow, faster, and use less memory.