3

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 ?

8
  • 1
    I'd say it's impossible. Commented Aug 3, 2014 at 10:23
  • Why would one write a static function in a trait in the first place? Commented Aug 3, 2014 at 10:23
  • @nietonfir It was just a copy / paste from another piece of code for the example, nevermind. Commented Aug 3, 2014 at 10:26
  • 2
    This comment on the documentation page says that trait methods can always be called as if they were defined as static methods. Commented Aug 3, 2014 at 10:47
  • 1
    Can you make it private in the trait, then use use Trait { hello_world as public hello_world; } to make it public in ClassWithTrait? Commented Aug 3, 2014 at 11:08

2 Answers 2

6

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 ;}
    ...
}
Sign up to request clarification or add additional context in comments.

2 Comments

@Barmar small typo use construct
Thanks. FYI, for trivial typos, you can use the edit link instead of commenting.
2

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 !';
    }

}

2 Comments

Working fine, but I think Barmar's answer is much more clear on what is the intent of the workaround and what is happening. Got my upvote though !
...and Barmar got mine ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.