'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 1:[1]

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

Solution 2:[2]

Another alternative would be privatizing the methods you don't want:

class MyClass1 {
    use HelloWorld { sayHello as protected; }
}

see also: https://www.php.net/manual/en/language.oop5.traits.php

it says it can't change to private, but I found it worked on my end...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 SomeOne_1