How to prevent use of trait methods out of “use” s

2019-03-31 09:42发布

I'd like to know if there is any way to prevent the use of trait methods out of any class context in PHP ?

Let me explain what I want with a short example, here is my current code :

// File : MyFunctions.php
trait MyFunctions {

    function hello_world() {
        echo 'Hello World !';
    }

}

// File : A.php
include 'MyFunctions.php';

class A {

    use MyFunctions;

}

// File : testTraits.php
include 'A.php';

hello_world(); // Call to undefined function -> OK, expected
A::hello_world(); // Hello World ! -> OK, expected
MyFunctions::hello_world(); // Hello World ! -> Maybe OK, but not expected, I'd like to prevent it

PHP manual page about traits is very comprehensive, and a lot of cases are treated, but not this one (http://php.net/manual/en/language.oop5.traits.php)

I desperatly tried to remove "static" and use "public", "protected", "private", but of course, it just didn't work. I've no other ideas so far, so maybe I'm missing something, or it's just impossible ?

标签: php traits
2条回答
劫难
2楼-- · 2019-03-31 10:14

Using traits in PHP establishes the contract that functions defined in the trait can always be called as if they were defined as static methods.

If you really must, you can work around that behaviour dynamically by wrapping your function with a test that determines whether there is a match between magic constants __CLASS__ (the name of the class the trait is used in) and __TRAIT__ (the name of the trait itself).

If there is a match, then the method was not used as intended and you tweak its behaviour accordingly.

So your example would become:

trait MyFunctions {

    function hello_world() {
        if (__CLASS__ == __TRAIT__) {
            die('Sorry');
        }
        echo 'Hello World !';
    }

}
查看更多
家丑人穷心不美
3楼-- · 2019-03-31 10:17

Use the visibility changing feature when using a trait:

trait MyFunctions {

    private function _hello_world() {
        echo 'Hello World !';
    }

}

class A {

    use MyFunctions { _hello_world as public hello_world ;}
    ...
}
查看更多
登录 后发表回答