AOP面向切面编程(Aspect Oriented Programming)

Phalcon\Aop 是一个通用组件,以非侵入的方式将系统级的功能代码切入到目标类的指定方法、成员变量上。

  1. <?php
  2.  
  3. class MyServices {
  4. private $val = 0;
  5. public function doVal() {
  6. echo 'Myval='.$this->val.PHP_EOL;
  7. $this->val++;
  8. echo 'Myval='.$this->val.PHP_EOL;
  9. }
  10. }
  11.  
  12. $pointcut = 'MyServices::doVal()';
  13. $advice = function($joinpoint){
  14. echo $joinpoint->getProperty('val').'='.$$joinpoint->setProperty('val', 3).PHP_EOL;
  15. };
  16. Phalcon\Aop::addBefore($pointcut, $advice);
  17.  
  18. $services = new MyServices();
  19. $services->doVal();

在上面的例子中,我们在 doVal 方法调用前修改了 val 的值。

可以把对成员变量的访问和更新作为通知的连接点:

  1. <?php
  2.  
  3. class MyServices {
  4. private $val = 0;
  5. public function doVal() {
  6. echo 'Myval='.$this->val.PHP_EOL;
  7. $this->val++;
  8. echo 'Myval='.$this->val.PHP_EOL;
  9. }
  10. }
  11.  
  12. $pointcut = 'read MyServices->val';
  13. $advice = function($joinpoint){
  14. echo $joinpoint->getPropertyName().'='.$$joinpoint->setPropertyValue().PHP_EOL;
  15. };
  16. Phalcon\Aop::addBefore($pointcut, $advice);
  17.  
  18. $pointcut = 'write MyServices->val';
  19. $advice = function($joinpoint){
  20. $joinpoint->setAssignedValue(2);
  21. };
  22. Phalcon\Aop::addBefore($pointcut, $advice);
  23.  
  24. $services = new MyServices();
  25. $services->doVal();

使用 AOP 实现业务层读写分离

该功能通过将对方法 Phalcon\Mvc\Model\Query::getConnection() 的访问作为连接点来实现:

  1. <?php
  2.  
  3. $pointcut = 'Phalcon\Mvc\Model\Query::getConnection()';
  4. $advice = function($joinpoint){
  5. // 通过参数来选择
  6. $args = $joinpoint->getArguments();
  7. // 通过 SQL 类型来选择
  8. $query = $joinpoint->getObject();
  9. $query->getType(); // Phalcon\Mvc\Model\Query::TYPE_SELECT
  10. // ...
  11. return $db;
  12. };
  13. Phalcon\Aop::addAfter($pointcut, $advice);

或者通过将对方法 Phalcon\Mvc\Model\Query::getReadConnection()Phalcon\Mvc\Model\Query::getWriteConnection() 的访问作为连接点来实现。

原文: http://www.myleftstudio.com/reference/aop.html