利用反射给类中方法加钩子
有一个类如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class Test { private $name = 'ok' ; public function __beforePrintname() { echo '调用方法前' ; } public function printName() { echo 'ok' ; } public function __afterPrintname() { echo '调用方法后' ; } } |
我们希望在实例化后调用printName方法前能调用__beforePrintname,调用printName后能调用__afterPrintname;给这个方法前后都加一个钩子方法
我们可以使用反射来实现,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | 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); } } } } } } } |
测试:
1 2 | $test = new Proxy( 'Test' ); $test->printName(); |
输出:
调用方法前ok调用方法后
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步