[英]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.