php的类中实现任意一个方法执行后,始终执行一个指定的类内部方法?

在 PHP 中,如果你希望在类中的任意一个方法执行后,始终执行一个指定的类内部方法,你可以使用魔术方法 __call() 或者更具体的 __callStatic()(对于静态方法),或者使用更通用的 __after() 方法(虽然 PHP 没有内置的 __after() 方法,但你可以自己实现)。

但是,对于更常见的需求,PHP 提供了一个特性叫做“析构函数”(__destruct()),它会在对象被销毁时自动调用。然而,析构函数并不是在每个方法执行后都会调用,而是在对象不再需要时(例如,当没有变量引用该对象时)才会被调用。

为了实现你想要的功能,你可以采用以下两种常见策略之一:

  1. 使用 __call() 方法拦截并代理方法调用

你可以在你的类中重写 __call() 方法,该方法会在调用类中未定义或不可访问的方法时被调用。然后你可以在这个方法内部调用实际的方法,并在之后调用你的“始终执行”的方法。

class MyClass {  
    private function alwaysExecute() {  
        // 这里是你想要在每个方法后执行的代码  
        echo "This is always executed after a method call.\n";  
    }  
  
    public function __call($name, $arguments) {  
        // 假设你有一个方法来检查并调用实际的方法,这里简化处理  
        if (method_exists($this, $name)) {  
            $method = new ReflectionMethod($this, $name);  
            $method->invokeArgs($this, $arguments);  
        }  
  
        // 调用始终执行的方法  
        $this->alwaysExecute();  
    }  
  
    // 你的其他方法...  
    public function myMethod() {  
        echo "This is myMethod.\n";  
    }  
}  
  
// 使用示例  
$obj = new MyClass();  
$obj->myMethod(); // 输出 "This is myMethod.\nThis is always executed after a method call.\n"

注意,__call() 只会在调用未定义或不可访问的方法时触发。如果所有方法都是公有的并且被定义了,__call() 将不会被调用。

  1. 使用模板方法模式或类似策略

另一种策略是在你的类中定义一个“模板方法”,该方法负责调用其他方法,并在它们之后调用你的“始终执行”的方法。你需要确保所有的公共方法都通过模板方法被调用。

class MyClass {  
    private function alwaysExecute() {  
        // 这里是你想要在每个方法后执行的代码  
        echo "This is always executed after a method call.\n";  
    }  
  
    public function doMyMethod() {  
        // 执行实际的方法逻辑  
        $this->myMethod();  
  
        // 调用始终执行的方法  
        $this->alwaysExecute();  
    }  
  
    // 私有方法,只能通过 doMyMethod() 调用  
    private function myMethod() {  
        echo "This is myMethod.\n";  
    }  
  
    // 其他类似的“do”方法...  
}  
  
// 使用示例  
$obj = new MyClass();  
$obj->doMyMethod(); // 输出 "This is myMethod.\nThis is always executed after a method call.\n"

在这个例子中,你需要确保所有的公共功能都是通过类似 doMyMethod() 的“do”方法来调用的,而不是直接调用 myMethod()。这样你就可以确保在每个公共功能之后都执行了 alwaysExecute() 方法。

Was this helpful?

0 / 0

发表回复 0