_call() 和 __callStatic() 魔术方法在什么情况下会被调用?

在 PHP 中,__call()__callStatic() 是两个特殊的魔术方法,它们在特定情况下被自动调用。这两个方法用于处理对未定义或不可访问方法的调用。

__call()

__call() 方法在尝试调用一个对象的非公开(protected 或 private)或不存在的方法时被调用。这个方法必须声明为 public,通常有两个参数:

  1. $name - 字符串,表示被调用的方法名。
  2. $arguments - 一个数组,包含传递给方法的参数。

这种机制允许开发者编写灵活的代码,可以在运行时动态地捕捉方法调用并处理它们。例如,可以用来实现代理模式(proxy pattern)、日志记录或动态API等。

示例代码:

class MyClass {
    public function __call($name, $arguments) {
        echo "尝试调用非公开或不存在的方法 '$name' ";
        echo "带有参数:" . implode(', ', $arguments) . "\n";
    }
}

$obj = new MyClass();
$obj->runTest('param1', 'param2');  // 因为 MyClass 中不存在 runTest 方法,所以 __call() 被触发

__callStatic()

__callStatic() 方法在尝试调用一个类的非公开(protected 或 private)或不存在的静态方法时被调用。与 __call() 类似,这个方法也必须被声明为 public,并且通常有两个参数:

  1. $name - 字符串,表示被调用的静态方法名。
  2. $arguments - 一个数组,包含传递给静态方法的参数。

__callStatic() 允许开发者捕捉对静态方法的调用,即使这些方法未被定义。这可以用于类似的用途,如动态行为的实现、API调用等。

示例代码:

class MyStaticClass {
    public static function __callStatic($name, $arguments) {
        echo "尝试调用非公开或不存在的静态方法 '$name' ";
        echo "带有参数:" . implode(', ', $arguments) . "\n";
    }
}

MyStaticClass::testStatic('value1', 'value2');  // MyStaticClass 中不存在 testStatic 方法,所以 __callStatic() 被触发

总结

总之,__call()__callStatic() 魔术方法分别用于实例方法和静态方法的动态调用处理。它们在类中方法不存在或不可访问时提供了一种可拦截并处理这些调用的方式,增加了代码的灵活性和动态性。这两个方法在设计模式实现、动态代理、API封装等方面非常有用。