Search code examples
phptraits

Can I import only some selected methods from a trait?


If a trait contains multiple properties and methods, can I only import few of those?

trait MyTrait
{
    public function ok()
    {
        echo 'ok';
    }

    public function nope()
    {
        echo 'not ok';
    }
}

class MyClass
{
    use MyTrait {
        MyTrait::ok as ok;
    }
}

$mc = new MyClass;

$mc->ok(); // This should work
$mc->nope(); // This shouldn't work

The issue is that I am developing package and want to import a couple of methods from another package (to ensure that certain actions works the same way). But the trait of those methods contains 11 properties and 76 methods. I don't want all of that polluting my namespace.

Is there a way to selectively import? Or must I fall back to some reflection trickery?


Solution

  • You can't do that, as far as I know. Using a trait basically includes its contents into a class. The properties and methods it defines may very well depend on each other.

    One alternative option would be to manually define the methods you want in a class that doesn't include the trait, but instead delegates the calls to an instance of a class that does.

    Something like this:

    trait MyTrait
    {
      public function ok(): void
      {
        echo 'ok';
      }
    
      public function nope(): void
      {
        echo 'not ok';
      }
    }
    
    class MyTraitDelegate
    {
      use MyTrait;
    }
    
    class MyClass
    {
      private MyTraitDelegate $traitDelegate;
    
      public function __construct()
      {
        $this->traitDelegate = new MyTraitDelegate();
        // Note: you could also inject it, but in this case, not sure it's worth.
      }
    
      public function ok(): void
      {
        $this->traitDelegate->ok();
      }
    }
    
    $mc = new MyClass;
    
    $mc->ok();   // works
    $mc->nope(); // method not found