魔术方法是PHP的重载机制,当调用类中不存在或不可访问的静态方法是,将调用类中的__callStatic方法。
基于这种重载机制,就有很多使用技巧可以利用,下边举了两个例子。
后期静态绑定
laravel eloquent orm的model抽象类中也有后期静态绑定的使用,最常用的比如$table变量。
当然不局限于orm,很多其他组件当中也有使用,开发架构中也可以使用。
abstract class Model
{
public static function getTable()
{
return __FUNCTION__ . ':' . static::$table;
}
private function find(...$args)
{
return __FUNCTION__ . ':' . implode('', $args);
}
public static function __callStatic($method, $args)
{
return static::$method(...$args);
}
}
class UserModel extends Model
{
protected static $table = 'users';
}
echo UserModel::getTable(); // 一般后期静态绑定使用方式
echo "\n";
echo UserModel::find('a', 'b'); // 结合魔术方法的后期静态绑定使用方式
/*
output:
getTable:users
find:ab
*/
链式调用
laravel eloquent orm的构造查询器也是类似思路实现的,但是要复杂很多。
abstract class Model
{
public static function getTable()
{
echo __FUNCTION__ . ':' . static::$table;
return (new static);
}
private function find(...$args)
{
echo __FUNCTION__ . ':' . implode('', $args);
return (new static);
}
public static function __callStatic($method, $args)
{
return static::$method(...$args);
}
public function __call($method, $args)
{
return $this->$method(...$args);
}
}
class UserModel extends Model
{
protected static $table = 'users';
}
UserModel::getTable()->find('a', 'b')->find('c', 'd');
/*
output:
getTable:usersfind:abfind:cd
*/
参考链接
https://www.php.net/manual/zh/language.oop5.late-static-bindings.php