在PHP中,利用__call(),可实现方法运行前/后执行指定的程序片段。
下面演示下,在test方法执行后自动执行afterTest方法
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
| trait A{ public function __call($method, $args){ if (!method_exists($this, $method)) { throw new Exception('no such method: ' . $method); } $afterMethod = 'after'.ucfirst($method); if (method_exists($this, $afterMethod)) { $rs = call_user_func_array([$this, $method], $args); if ($rs['code'] == 0) { call_user_func_array([$this, $afterMethod], $rs); return $rs; } } else { return call_user_func_array([$this, $method], $args); } }
private function afterTest(...$args){ print_r($args); } }
Class B{ use A; protected function test($id,$name): array{ return $id>10 ? ['code'=>1,'msg'=>'ok'] : ['code'=>0,'msg'=>'error']; } }
$rs = (new B())->test(7,'张三');
|
输出结果为:
Array ( [0] => 0 [1] => error )
不难看出,这种处理方式存在以下两个缺陷:
- 方法需设为外界不可用,protected/privated,在IDE中就无法跳转,其他人维护起来比较困难;
- 代码耦合度高,相互影响,不利于后期扩展。