php aop 实现
PHP 实现 AOP(面向切面编程)
AOP(Aspect-Oriented Programming)是一种编程范式,用于将横切关注点(如日志、事务、权限等)从业务逻辑中分离。PHP 原生不支持 AOP,但可通过以下方式实现:
使用 Go! AOP 框架
Go! AOP 是 PHP 中流行的 AOP 实现库,基于 PHP 反射和动态代理。
安装:
composer require goaop/framework
示例代码:

use Go\Core\AspectContainer;
use Go\Core\AspectKernel;
class LoggingAspect implements \Go\Aop\Aspect
{
public function beforeMethod(\Go\Aop\Intercept\MethodInvocation $invocation)
{
echo "Logging: " . $invocation->getMethod()->getName() . "\n";
}
}
class ApplicationAspectKernel extends AspectKernel
{
protected function configureAop(AspectContainer $container)
{
$container->registerAspect(new LoggingAspect());
}
}
// 初始化内核
ApplicationAspectKernel::getInstance()->init([
'debug' => true,
'appDir' => __DIR__,
]);
// 目标类
class Service
{
public function doSomething()
{
echo "Doing something...\n";
}
}
// 调用
$service = new Service();
$service->doSomething();
输出:
Logging: doSomething
Doing something...
使用 PHP-DI 和 AOP 插件
PHP-DI 是一个依赖注入容器,支持 AOP 扩展。
安装:

composer require php-di/php-di
composer require php-di/aop-bridge
示例代码:
use DI\ContainerBuilder;
use DI\Aop\Pointcut;
$builder = new ContainerBuilder();
$builder->useAutowiring(true);
$builder->useAnnotations(true);
$builder->addDefinitions([
'log' => function() {
return new class {
public function before() {
echo "Logging before method\n";
}
};
},
]);
$container = $builder->build();
// 定义切面
Pointcut::beforeMethod(
'Service::doSomething',
[$container->get('log'), 'before']
);
class Service
{
public function doSomething()
{
echo "Doing something...\n";
}
}
// 调用
$service = $container->get('Service');
$service->doSomething();
手动实现代理模式
对于简单场景,可通过设计模式手动实现 AOP 效果。
interface ServiceInterface
{
public function doSomething();
}
class Service implements ServiceInterface
{
public function doSomething()
{
echo "Doing something...\n";
}
}
class ServiceProxy implements ServiceInterface
{
private $service;
public function __construct(ServiceInterface $service)
{
$this->service = $service;
}
public function doSomething()
{
echo "Logging before...\n";
$this->service->doSomething();
}
}
// 调用
$service = new ServiceProxy(new Service());
$service->doSomething();
使用 Symfony 的 AOP 组件
Symfony 通过 EventDispatcher 实现类似 AOP 的功能。
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event;
class ServiceEvent extends Event
{
public const PRE_DO_SOMETHING = 'service.pre_do_something';
private $service;
public function __construct($service)
{
$this->service = $service;
}
}
$dispatcher = new EventDispatcher();
$dispatcher->addListener(
ServiceEvent::PRE_DO_SOMETHING,
function (ServiceEvent $event) {
echo "Logging before...\n";
}
);
class Service
{
private $dispatcher;
public function __construct(EventDispatcher $dispatcher)
{
$this->dispatcher = $dispatcher;
}
public function doSomething()
{
$this->dispatcher->dispatch(
new ServiceEvent($this),
ServiceEvent::PRE_DO_SOMETHING
);
echo "Doing something...\n";
}
}
// 调用
$service = new Service($dispatcher);
$service->doSomething();
注意事项
- 性能影响:动态代理会引入额外开销,生产环境需测试性能。
- 调试难度:AOP 可能使调用栈复杂化,增加调试难度。
- 适用场景:适合日志、事务、缓存等横切关注点,避免过度使用。
以上方法可根据项目需求选择,框架集成(如 Go! AOP)适合复杂场景,手动代理适合简单需求。






