有一个类如下所示:
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调用方法后