php aop 实现
PHP AOP 实现方法
使用 Go! AOP 框架
Go! AOP 是一个流行的 PHP AOP 实现框架,基于 PHP 的 traits 和魔术方法实现。安装方式如下:
composer require goaop/framework
定义切面类示例:
use Go\Aop\Aspect;
use Go\Aop\Intercept\MethodInvocation;
use Go\Lang\Annotation\Before;
class LoggingAspect implements Aspect {
/
* @Before("execution(public App\Service\*->*(*))")
*/
public function logBeforeMethod(MethodInvocation $invocation) {
$method = $invocation->getMethod();
echo "Calling method: " . $method->name . "\n";
}
}
配置 AOP 内核:
use Go\Core\AspectKernel;
use Go\Core\AspectContainer;
class ApplicationAspectKernel extends AspectKernel {
protected function configureAop(AspectContainer $container) {
$container->registerAspect(new LoggingAspect());
}
}
使用 PHP-DI 和 AOP 集成
PHP-DI 可以与 AOP 结合使用,通过容器拦截方法调用:
use DI\ContainerBuilder;
use DI\Aop\Aspect;
$builder = new ContainerBuilder();
$builder->addDefinitions([
'cache.aspect' => \DI\create(CacheAspect::class),
]);
$container = $builder->build();
定义缓存切面:
class CacheAspect implements Aspect {
public function around(MethodInvocation $invocation) {
$key = $invocation->getMethod()->name;
if ($cached = $this->cache->get($key)) {
return $cached;
}
$result = $invocation->proceed();
$this->cache->set($key, $result);
return $result;
}
}
使用原生 PHP 实现简单 AOP
通过 trait 和魔术方法实现基础 AOP 功能:
trait AopTrait {
public function __call($method, $args) {
if (method_exists($this, 'before' . ucfirst($method))) {
call_user_func([$this, 'before' . ucfirst($method)], $args);
}
$result = call_user_func_array([$this, $method], $args);
if (method_exists($this, 'after' . ucfirst($method))) {
call_user_func([$this, 'after' . ucfirst($method)], $args, $result);
}
return $result;
}
}
使用 Ray.Aop 库
Ray.Aop 是另一个轻量级 PHP AOP 实现:
use Ray\Aop\Bind;
use Ray\Aop\Compiler;
use Ray\Aop\Matcher;
$compiler = new Compiler($_ENV['TMP_DIR']);
$bind = (new Bind)->bindInterceptors(
'charge', // 方法名
[new LoggingInterceptor()] // 拦截器数组
);
$service = $compiler->newInstance(OrderService::class, [], $bind);
定义拦截器:
class LoggingInterceptor implements MethodInterceptor {
public function invoke(MethodInvocation $invocation) {
echo "Before method call\n";
$result = $invocation->proceed();
echo "After method call\n";
return $result;
}
}
性能优化建议
AOP 实现会带来性能开销,生产环境中建议:
- 使用 OPcache 缓存生成的代理类
- 避免在热点路径上使用过多切面
- 考虑使用编译时织入而非运行时织入
常见应用场景
- 日志记录
- 性能监控
- 事务管理
- 缓存处理
- 权限验证
- 输入验证
- 异常处理
每种实现方式各有优缺点,选择时应考虑项目规模、性能要求和团队熟悉程度。框架集成的方案如 Go! AOP 功能完善但较重,原生实现轻量但功能有限。







