PHP 实现aop
PHP 实现 AOP(面向切面编程)
AOP(Aspect-Oriented Programming)是一种编程范式,用于将横切关注点(如日志、事务、权限等)从业务逻辑中分离出来。PHP 本身不原生支持 AOP,但可以通过以下方式实现:
使用 Go! AOP 框架
Go! AOP 是一个流行的 PHP AOP 框架,基于 PHP 反射和动态代理实现。
安装:
composer require goaop/framework
示例代码:
use Go\Core\AspectKernel;
use Go\Core\AspectContainer;
class LoggingAspect implements \Go\Aop\Aspect
{
public function beforeMethod(\Go\Aop\Intercept\MethodInvocation $invocation)
{
echo "Logging before: " . $invocation->getMethod()->name . "\n";
}
}
class ApplicationAspectKernel extends AspectKernel
{
protected function configureAop(AspectContainer $container)
{
$container->registerAspect(new LoggingAspect());
}
}
ApplicationAspectKernel::getInstance()->init([
'debug' => true,
'appDir' => __DIR__,
]);
class ExampleService
{
public function doSomething()
{
echo "Doing something...\n";
}
}
$service = new ExampleService();
$service->doSomething();
使用 PHP-DI 和 AOP 插件
PHP-DI 是一个依赖注入容器,支持通过 AOP 插件实现切面编程。
安装:
composer require php-di/php-di
composer require php-di/aop-bridge
示例代码:
use DI\ContainerBuilder;
use DI\Aop\AroundInterceptor;
$containerBuilder = new ContainerBuilder();
$containerBuilder->useAutowiring(true);
$containerBuilder->useAnnotations(true);
$containerBuilder->enableAop();
$container = $containerBuilder->build();
$container->set('loggingInterceptor', new class implements AroundInterceptor {
public function invoke(callable $proceed, $object, $method, $args)
{
echo "Before: $method\n";
$result = $proceed();
echo "After: $method\n";
return $result;
}
});
class ExampleService
{
/
* @Around("loggingInterceptor")
*/
public function doSomething()
{
echo "Doing something...\n";
}
}
$service = $container->get('ExampleService');
$service->doSomething();
手动实现代理模式
如果不想依赖框架,可以通过代理模式手动实现 AOP。
示例代码:
interface ServiceInterface
{
public function doSomething();
}
class RealService implements ServiceInterface
{
public function doSomething()
{
echo "Doing something...\n";
}
}
class ServiceProxy implements ServiceInterface
{
private $realService;
public function __construct(ServiceInterface $realService)
{
$this->realService = $realService;
}
public function doSomething()
{
echo "Before: doSomething\n";
$this->realService->doSomething();
echo "After: doSomething\n";
}
}
$realService = new RealService();
$proxy = new ServiceProxy($realService);
$proxy->doSomething();
使用注解和反射
通过 PHP 的反射和注解功能,可以实现简单的 AOP。
示例代码:
/
* @Annotation
*/
class Loggable {}
class ExampleService
{
/
* @Loggable
*/
public function doSomething()
{
echo "Doing something...\n";
}
}
function invokeWithLogging($object, $methodName)
{
$reflectionMethod = new ReflectionMethod($object, $methodName);
$annotations = $reflectionMethod->getAttributes(Loggable::class);
if (!empty($annotations)) {
echo "Before: $methodName\n";
}
$reflectionMethod->invoke($object);
if (!empty($annotations)) {
echo "After: $methodName\n";
}
}
$service = new ExampleService();
invokeWithLogging($service, 'doSomething');
选择建议
- Go! AOP:适合需要完整 AOP 功能的项目,支持切入点表达式和动态代理。
- PHP-DI + AOP:适合已使用 PHP-DI 的项目,集成方便。
- 手动代理:适合简单场景或学习 AOP 原理。
- 注解和反射:适合轻量级需求,无需额外依赖。
以上方法均可实现 AOP,具体选择取决于项目需求和技术栈。







