如何处理PHP中不存在__invoke()方法?

时间:2017-09-03 06:11:37

标签: php

神奇的 __ call() __ callStatic 几乎可以处理类中任何不存在的方法,但有没有办法处理一个不存在的神奇方法类?!

以下是我需要的原因示例:

我有一个名为 DoSomething 的课程:

class DoSomething{
   public function ok(){
      echo 'Something!';
   }
}

我想把这个类称为函数是有原因的!应该调用该类的 __ invoke 函数:

$doSomething = new DoSomething();

$doSomething();

通常这样做,该类应该寻找 __ invoke 函数,但在我的情况下,我不能在我的类中声明该函数( DoSomething ),如果 __ invoke 不存在,我希望能够调用另一个函数(例如 ok())。

我期待这样的事情发挥作用,但当然没有:)

public function __call($class, $arguments)
{
    $object = IoC::resolve($class);

    $object->ok(...$arguments);
}

主要目标是将类用作函数,而不必声明__invoke方法。处理函数不存在错误并改为调用另一个函数。

我认为这真的很酷:D我很感激建议或其他解决方案来实现这一目标。

1 个答案:

答案 0 :(得分:2)

内部解决方案

提取abstract

您可以提取abstract类并让您的类扩展它:

<?php

abstract class Invokable
{
    public function __invoke()
    {
        return $this->ok();
    }

    abstract public function ok();
}

class DoSomething extends Invokable
{
    public function ok()
    {
        echo 'Something';
    }
}

$doSomething = new DoSomething();

echo $doSomething();

有关示例,请参阅:

提取特征

您可以提取特征并让您的课程使用它:

<?php

trait InvokableTrait
{
    public function __invoke()
    {
        return $this->ok();
    }
}

class DoSomething
{
    use InvokableTrait;

    public function ok()
    {
        echo 'Something';
    }
}

$doSomething = new DoSomething();

echo $doSomething();    

有关示例,请参阅:

外部解决方案

创建代理

您可以创建一个代理(装饰器)来组成不可调用的对象:

<?php

class InvokableDecorator
{
    private $decorated;

    public function __construct($decorated)
    {
        $this->decorated = $decorated; 
    }

    public function __call($name, $arguments)
    {
        /**
         * delegate to decorated object if the method exists
         */ 
        if (method_exists($this->decorated, $name)) {
            return $this->decorated->{$name}($arguments);
        }
    }

    public function __invoke() 
    {        
        return $this->decorated->ok();
    }        
}

class DoSomething
{
    public function ok()
    {
        echo 'Something';
    }
}

$doSomething = new InvokableDecorator(new DoSomething());

echo $doSomething();

有关示例,请参阅:

创建处理程序

您可以创建一个处理程序来负责外部确定:

<?php

class Handler
{
    public function handle($subject)
    {
        if (is_callable($subject)) {
            return $subject();
        }

        if (method_exists($subject, 'ok')) {
            return $subject->ok();
        }

        throw new \BadMethodCallException(sprintf(
            'Unable to handle instance of "%s"',
            get_class($subject)
        ));
    }        
}

class DoSomething
{
    public function ok()
    {
        echo 'Something';
    }
}

$handler = new Handler();

echo $handler->handle(new DoSomething());

有关示例,请参阅: