有一个类如下所示:
class Test { private $name = 'ok'; public function __beforePrintname() { echo '调用方法前'; } public function printName() { echo 'ok'; } public function __afterPrintname() { echo '调用方法后'; } }
我们希望在实例化后调用printName方法前能调用__beforePrintname,调用printName后能调用__afterPrintname;给这个方法前后都加一个钩子方法
我们可以使用反射来实现,代码如下:
class Proxy { private $arrObject = []; public function __construct($obj) { $this->arrObject[] = new $obj(); } public function __call($name, $arguments) { foreach ($this->arrObject as $obj) { $ref = new ReflectionClass($obj); if ($method = $ref->getMethod($name)) { if ($method->isPublic()) { // 调用方法前 $beforeMethodName = '__before' . $name; if ($ref->hasMethod($beforeMethodName)) { $beforeMethod = $ref->getMethod($beforeMethodName); if ($beforeMethod->isPublic()) { $beforeMethod->invoke($obj, $arguments); } } // 调用方法 $method->invoke($obj, $arguments); // 调用方法后 $afterMethodName = '__after' . $name; if ($ref->hasMethod($afterMethodName)) { $afterMethod = $ref->getMethod($afterMethodName); if ($afterMethod->isPublic()) { $afterMethod->invoke($obj, $arguments); } } } } } } }
测试:
$test = new Proxy('Test'); $test->printName();
输出:
调用方法前ok调用方法后