PHP - 使用静态方法动态扩展父 class
PHP - dynamically extend parent class with static methods
考虑以下因素:
class A
{
public static function bark()
{ echo 'woof'; }
}
class B extends A
{
public static function speak()
{ echo 'hello'; }
}
A::speak();
// Fatal error: Call to undefined method A::speak()
如何使用您需要在 class 中全局可用的方法扩展 class 以及未知但在 运行 处加载的方法-时间,取决于您的应用程序流程?
是的,我们可以制作 traits
并将 use
放在 class 中,例如:
trait B
{
public static function speak()
{ echo 'hello'; }
}
class A
{
use B;
public static function bark()
{ echo 'woof'; }
}
A::speak();
// hello
- 但随后
use B
不会被动态调用,因此您必须更新 class A 以使用每个可用的新特征 - 手动。
这很荒谬,为什么要强迫开发人员绞尽脑汁来尝试完成如此根本上简单的事情?
有没有人知道如何以干净的方式完成此操作?我的意思是我通过使用单例、命名空间、回调和作品看到了一些令人印象深刻的方法,但在每种情况下,它都需要比真正需要的更多的代码和重复编程。
要么,要么我完全错过了船哈哈!
提前致谢,我们将不胜感激并慷慨投票。
我认为只要发挥一些创造力,您就可以使用 __call 魔术方法。
你可以这样做:
class A
{
/**
* @var array
*/
protected $methods = [];
public function __call($name, $arguments)
{
if (!empty($this->methods[$name]) && is_callable($this->methods[$name])) {
return call_user_func_array($this->methods[$name], $arguments);
}
}
public function addMethod($name, Closure $method)
{
$this->methods[$name] = $method;
}
}
// get class instance (A have no methods except of addMethod)
$instance = new A();
// add methods on runtime
$instance->addMethod('sum', function($num1, $num2) {
return $num1 + $num2;
});
$instance->addMethod('sub', function($num1, $num2) {
return $num1 - $num2;
});
// use methods exactly the same way as implemented fixed on class
echo $instance->sum(2, 2);
echo $instance->sub(3, 2);
当然您也可以将 __callStatic 用于静态方法。如果你想让它更复杂一点,也可以使用依赖注入的概念来添加对象而不是方法。然后在注入的对象中查找被调用的方法,找到后调用。
我希望这至少能给你一个好主意。
考虑以下因素:
class A
{
public static function bark()
{ echo 'woof'; }
}
class B extends A
{
public static function speak()
{ echo 'hello'; }
}
A::speak();
// Fatal error: Call to undefined method A::speak()
如何使用您需要在 class 中全局可用的方法扩展 class 以及未知但在 运行 处加载的方法-时间,取决于您的应用程序流程?
是的,我们可以制作 traits
并将 use
放在 class 中,例如:
trait B
{
public static function speak()
{ echo 'hello'; }
}
class A
{
use B;
public static function bark()
{ echo 'woof'; }
}
A::speak();
// hello
- 但随后
use B
不会被动态调用,因此您必须更新 class A 以使用每个可用的新特征 - 手动。 这很荒谬,为什么要强迫开发人员绞尽脑汁来尝试完成如此根本上简单的事情?
有没有人知道如何以干净的方式完成此操作?我的意思是我通过使用单例、命名空间、回调和作品看到了一些令人印象深刻的方法,但在每种情况下,它都需要比真正需要的更多的代码和重复编程。 要么,要么我完全错过了船哈哈! 提前致谢,我们将不胜感激并慷慨投票。
我认为只要发挥一些创造力,您就可以使用 __call 魔术方法。 你可以这样做:
class A
{
/**
* @var array
*/
protected $methods = [];
public function __call($name, $arguments)
{
if (!empty($this->methods[$name]) && is_callable($this->methods[$name])) {
return call_user_func_array($this->methods[$name], $arguments);
}
}
public function addMethod($name, Closure $method)
{
$this->methods[$name] = $method;
}
}
// get class instance (A have no methods except of addMethod)
$instance = new A();
// add methods on runtime
$instance->addMethod('sum', function($num1, $num2) {
return $num1 + $num2;
});
$instance->addMethod('sub', function($num1, $num2) {
return $num1 - $num2;
});
// use methods exactly the same way as implemented fixed on class
echo $instance->sum(2, 2);
echo $instance->sub(3, 2);
当然您也可以将 __callStatic 用于静态方法。如果你想让它更复杂一点,也可以使用依赖注入的概念来添加对象而不是方法。然后在注入的对象中查找被调用的方法,找到后调用。 我希望这至少能给你一个好主意。