[英]PHP use static function to create new instance w/ Inheritance
所以我从Laravel那里得到了这个主意。 使用Laravel,您可以执行以下操作。
$user = new User;
$user->where('name', 'george')->get();
// which is the same as...
User::where('name', 'george')->get();
因此,我猜测User类具有__callStatic设置,因此它使新实例成为后备。 我能够使用以下代码复制该代码。
class Driver
{
protected static $instance = null;
public static function __callStatic($name, $args) {
$classname = get_called_class();
if (empty(static::$instance)) static::$instance = new $classname;
return static::$instance->$name(...$args);
}
}
但是,当我尝试多次继承该类时,就会出现问题。 我希望所有类都能够继承__callStatic并能够静态调用其祖先的任何公共函数。
class A extends Driver
{
public function hello() {
echo "hello";
return $this;
}
public function world() {
echo " world";
return $this;
}
}
class B extends A
{
public function name() {
echo "\nMy Name is George";
return $this;
}
}
class C extends B
{
// class can be empty
}
C::hello()->world()->name();
// returns: hello world
// My name is George
您遇到的问题是由于$ instance属性是静态的,并且在父类上声明的。 您的项目中只有一个实例属性,它是Driver的类属性。
有几种解决方法。 您可以在子类上定义$ instance,将Driver :: $ instance作为地图(数组)作为[className => instance],或者更好的是,完全摆脱该全局状态;)
无论如何,具有“类似单例”的$ instance结构的整个概念可能会在以后引起更多的问题。 考虑以下示例:
class Foo extends Driver
{
private $name;
public function named(string $name) : self
{
$this->name = $name;
return $this;
}
public function name() : string
{
return $this->name;
}
}
$alice = Foo::named('Alice');
$bob = Foo::named('Bob');
echo $alice->name(); // Outputs "Bob"!
$ alice仍然指向原始实例,但是由于Foo :: named('bob')将名称bob分配给了相同的实例,因此您不小心将Alice重命名为Bob。
您可能正在寻找的更像是:
abstract class Driver
{
public static function __callStatic(string $name, array $arguments)
{
$instance = new static;
$instance->$name(...$arguments);
return $instance;
}
}
这样,您每次都会创建新实例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.