神奇的 __ 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我很感激建议或其他解决方案来实现这一目标。
答案 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());
有关示例,请参阅: