Ari*_*ona 7 php aop cross-cutting-concerns
我对我正在为自定义框架开发的事件系统有所了解.
想象一下像这样的伪函数.
class Test
{
public function hi()
{
Event::add(__FUNCTION__ . 'is about to run.');
return "hi";
}
}
Run Code Online (Sandbox Code Playgroud)
想象一下,你需要为更多功能做同样的事情.(也许您想记录在运行时运行的函数,并希望将它们记录在单独的文件中.)
而不是这样做并手动将事件添加到函数中,我们可以做这样的事情吗?
class Test
{
public function hi()
{
return "hi";
}
}
// events.php (It's a pseudo code so may not work.)
// Imagine extend's purpose is to inject codes into target function
Event::bind('on', $className, $methodName, function() use ($className, $methodName)
{
return $className->$methodName->extend('before', Event::add(__FUNCTION__ . 'is about to run.'));
});
Run Code Online (Sandbox Code Playgroud)
我们的想法是注入hi()
内部的函数Test class
并注入我们通过extend
外部传递的任何函数.'before'
意味着注射必须在目标函数的第一线.
最后,事件和事件绑定将完全从函数中抽象出来.我希望能够在不改变功能的情况下绑定自定义的东西.
我有一种感觉,我们可以通过黑客攻击eval()
或玩弄来做到这一点call_user_func()
.不过我不确定.使用eval()
声音已经非常糟糕了.
我的问题是;
是的你可以。您可以使用GO使用AOP !适用于注释的AOP 框架。
例如,您想记录每个公共方法调用。而不是像这样添加到每个功能行。
namespace Acme;
class Controller
{
public function updateData($arg1, $arg2)
{
$this->logger->info("Executing method " . __METHOD__, func_get_args());
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
您可以对 Acme 命名空间的所有类的所有公共方法使用一个方面,如下所示:
use Go\Aop\Aspect;
use Go\Aop\Intercept\MethodInvocation;
use Go\Lang\Annotation\Before;
class LoggingAspect implements Aspect
{
/** @var null|LoggerInterface */
protected $logger = null;
/** ... */
public function __construct($logger)
{
$this->logger = $logger;
}
/**
* Method that should be called before real method
*
* @param MethodInvocation $invocation Invocation
* @Before("execution(public Acme\*->*())")
*/
public function beforeMethodExecution(MethodInvocation $invocation)
{
$obj = $invocation->getThis();
$class = is_object($obj) ? get_class($obj) : $obj;
$type = $invocation->getMethod()->isStatic() ? '::' : '->';
$name = $invocation->getMethod()->getName();
$method = $class . $type . $name;
$this->logger->info("Executing method " . $method, $invocation->getArguments());
}
}
Run Code Online (Sandbox Code Playgroud)
它看起来更复杂,但更灵活。