3

I'm fairly new to using traits in PHP and am wondering if there is a way to ensure that a class including a trait has particular properties.

I know that you can use something like the following to ensure the using class has particular methods.

protected abstract function some_function();

Is there a way to do the same kind of thing for member variables, since a trait has access to the member variables in the using class?

I can just document the requirement, but it would be nice to throw an exception in case a class trying to use a trait is missing a required property.

The closest that I can find is to create a function in the trait that attempts to grab the variable and return it ... and throw an exception if it is not found. Then the methods in the trait can use that to access the parent classes property instead of accessing them directly.

Thoughts, suggestions, and recommendations welcome ... as I am just getting used to traits.

The use case is that I have certain things that only run on the public face of the site and certain other things that only run on the private face of the site, but both share a common set of base functionality (various configuration settings, error handling, etc).

I could avoid using traits by making the class files for each of the inherited classes extremely long, but I'm trying to keep like functionality together in smaller files if possible.

I suppose one possibility would be to require an accessor variable in the calling class to return the wanted property.

abstract function get_my_value();

Anything else that might work cleanly?

Thanks in advance!

  • 2
    I am putting into a comment since it doesn't exactly answer your question. Anyway. There is no way to ensure things like that because trait is not part of the class. You can think of it (it's a bit oversimplified) as of an include for classes. It is a simple way of doing copy/paste without code duplication. If you have a shared functionality in your trait then this trait should already have everything to work by itself. If it doesn't you might already have some conceptual issues. – Aleksander Wons Jun 28 '15 at 18:12
  • Thanks awons. Reviewing what I was doing at the time I did have a couple of conceptual problems. – Privateer Aug 17 '15 at 21:49
5

The best way I have found to do this is as follows:

class This_Is_My_Class {
    use My_Trait;

    protected $prefix = '';

    function __construct() {
        $this->prefix = 'not_empty';
    }

    protected function get_prefix() {
       if ( empty($this->prefix) ) {
           throw new Exception("Prefix must be non empty.");
       }
       return $this->prefix;
    }

    ... rest of class here
}

trait My_Trait {

    abstract protected function get_prefix();

    protected function do_whatever() {
        $prefix = $this->get_prefix();
        ... do stuff
    }
}

Now, when using the trait, you properly get an exception when attempting to do things with it when the class using it either lacks the get_prefix function (due to the abstract declaration) or tries to use the prefix (due to the exception in the parent class).

Of course, if there is a cleaner solution to enforce that a class using a trait has a particular property, I'd love to hear it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.