php aop 实现
PHP AOP 实现方法
在 PHP 中实现面向切面编程(AOP)可以通过以下几种方式:
使用 Go! AOP 框架
Go! AOP 是一个流行的 PHP AOP 框架,它允许在不修改原有代码的情况下添加横切关注点。
安装 Go! AOP:
composer require goaop/framework
示例代码:
use Go\Core\AspectContainer;
use Go\Core\AspectKernel;
class LoggingAspect implements \Go\Aop\Aspect
{
public function beforeMethodExecution(\Go\Aop\Intercept\MethodInvocation $invocation)
{
$method = $invocation->getMethod();
echo "Executing: " . $method->getName() . "\n";
}
}
class ApplicationAspectKernel extends AspectKernel
{
protected function configureAop(AspectContainer $container)
{
$container->registerAspect(new LoggingAspect());
}
}
ApplicationAspectKernel::getInstance()->init([
'debug' => true,
'appDir' => __DIR__,
'cacheDir' => __DIR__.'/cache'
]);
使用 PHP-DI AOP 扩展
PHP-DI 是一个依赖注入容器,它提供了 AOP 功能。
安装 PHP-DI AOP:
composer require php-di/invoker php-di/aop-bridge
示例代码:
use DI\ContainerBuilder;
use DI\Aop\Pointcut;
$containerBuilder = new ContainerBuilder();
$containerBuilder->useAutowiring(true);
$containerBuilder->useAnnotations(true);
$containerBuilder->enableAop();
$container = $containerBuilder->build();
$container->set('logging.aspect', function() {
return new class {
public function beforeMethod()
{
echo "Before method execution\n";
}
};
});
Pointcut::create()
->intercept('MyClass::myMethod')
->before('logging.aspect:beforeMethod');
手动实现代理模式
对于简单的 AOP 需求,可以手动实现代理模式。
示例代码:
interface ServiceInterface
{
public function doSomething();
}
class RealService implements ServiceInterface
{
public function doSomething()
{
echo "Real work\n";
}
}
class ServiceProxy implements ServiceInterface
{
private $realService;
public function __construct(ServiceInterface $realService)
{
$this->realService = $realService;
}
public function doSomething()
{
echo "Before execution\n";
$this->realService->doSomething();
echo "After execution\n";
}
}
$service = new ServiceProxy(new RealService());
$service->doSomething();
使用 Symfony 的 AOP 组件
Symfony 框架也提供了 AOP 支持。
安装 Symfony AOP:
composer require symfony/aop-bundle
示例配置:
# config/packages/aop.yaml
aop:
aspects:
logging_aspect:
class: App\Aspect\LoggingAspect
pointcuts:
- 'execution(public App\Service\*->*(*))'
示例 Aspect 类:
namespace App\Aspect;
use Symfony\Component\Aop\BeforeAdvice;
class LoggingAspect
{
public function beforeAdvice(BeforeAdvice $advice)
{
echo "Before method: " . $advice->getMethod()->getName() . "\n";
}
}
选择建议
对于新项目,推荐使用 Go! AOP 框架,它功能全面且文档完善。对于已有项目,可以根据现有架构选择 PHP-DI 或 Symfony 的 AOP 实现。简单需求可以考虑手动代理模式实现。







