请教一个php框架中魔术常量__callStatic()的作用?

  1. 像__construct()这个很好理解, 对象创建完成后, 第一个被对象自动调用的方法. 很明显可以感受到可以用于初始化等方面.
  2. 但是__callStatic(), 在对象中调用一个不可访问方法时,__call() 会被调用。 在静态上下文中调用一个不可访问方法时,__callStatic() 会被调用. 如下代码展示的, 感觉好像"你传入什么, 最后就输出或返回什么, 这不类似于赋值吗?".
  3. tp5中, 比如用来操作数据库的Db类相关代码经常用到__callStatic()和__call(), 在对象中调用一个不可访问方法时, 就怎么怎么样......, 这种设计有什么精妙之处呢?
<?php
class Person {
    public function __call($name, $arguments){
        var_dump ($name, $arguments);
        echo "<hr>";
    }

    public static function __callStatic($name, $arguments){
        var_dump($name, $arguments);
    }
}

$p1 = new Person();
$p1 -> inexistent_method(1, 2, 6);          //调用不存在的普通方法
Person::inexistent_static_method(8, 9);      //调用不存在的静态方法

结果如下

string(17) "inexistent_method" array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(6) }
string(23) "nexistent_static_method" array(2) { [0]=> int(8) [1]=> int(9) }
阅读 2.6k
2 个回答

举个最简单的例子,现在项目需要一个缓存类,可能你会撸起袖子就开始写:

class Cache{
 
   public function storage($content){
      //写入缓存
   }
}

现在把写入缓存的逻辑在 storage 方法中实现了,使用的是文件存储,但是现在需求是通过配置可以管理缓存驱动,比如换成 Redis ,那么势必需要更改 storage 中的逻辑。这个时候就可以使用 __call() 方法来实现一下更换缓存驱动。

我们先创建 RedisCacheDriverFileCacheDriver


class RedisCacheDriver implements CacheDriverInterface{

   public function storage(){
    //redis 写入缓存逻辑
   }
}

class FileCacheDriver implements CacheDriverInterface{

   public function storage(){
    //文件写入缓存逻辑
   }
}
//缓存驱动接口
interface CacheDriverInterface{
   public function storage();
}

原先的 Cache 类:


class Cache{

   private $driver = null;

   public function __contruct(){
        $this->driver  = config('cache_driver');//从配置中获取
   }

   public function __call($name,$arguments){
     return $this->driver->$name(...$arguments);
   }
}

把每种缓存驱动的逻辑都写在自己的类中,这样维护也方便,对外提供也仅仅是 Cache 这个类而已。

推荐问题
宣传栏