用php实现aop切面编程

切面编程只是编程中的一种设计模式,php中有很多设计模式,我们常用的单例模式也算是一种设计模式,今天我们聊聊切面编程。
什么是切面编程,为什么要切面编程?
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程(也叫面向方面),可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。
切面编程的核心思想是,你新增加一些内容,不需要修改源代码,讲究的是“非侵入式编程”。而传统编程,假如,你要在某个方法调用增加一个日志,就需要修改源代码,这个属于侵入式编程了,可能会影响已经写好的代码,带来bug等问题,这个就是为什么要采用切面编程。
利用php扩展,实现切面编程
AOP-PHP是一个PECL扩展,您可以在PHP中使用面向方面的编程,无需编译或进行其他任何中间步骤。
AOP扩展的设计是最简单的方法,你可以认为PHP中的aop实现。
AOP旨在让横切关注点的分离(缓存,日志,安全,交易,……)
1.安装扩展。
sudo pecl install aop-beta
2.示例
<?php class MyServices { public function doAdminStuff1 () { //some stuff only the admin should do echo "Calling doAdminStuff1\n"; } public function doAdminStuff2 () { //some stuff only the admin should do echo "Calling doAdminStuff2\n"; } } function adviceForDoAdmin () { echo "AOP[1] Run\n"; } function adviceForDoAdmin2 () { echo "AOP[2] Run\n"; } aop_add_after('MyServices->doAdmin*()', 'adviceForDoAdmin'); aop_add_after('MyServices->doAdmin*()', 'adviceForDoAdmin2'); $o = new MyServices; $o->doAdminStuff1(); $o->doAdminStuff2();
执行结果
Calling doAdminStuff1 AOP[2] Run AOP[1] Run Calling doAdminStuff2 AOP[2] Run AOP[1] Run
可以看到,利用aop,可以轻松在要执行的函数前后,增加执行逻辑。而不需要修改原有类。
自己实现aop编程
其实实现aop切面编程的核心是,类的代理。
就是有个类是A,现在呢,你创建一个类是B。如果要调用A的方法,那么现在来调用B,B根据配置,来判断执行A的方法前后要做什么切面逻辑,然后B就依次处理前后,同时在B内部实例化A,调用A实际要调用的方法,就这么简单。
前面我们说过可用用swoole创建容器,利用容器实例化一个对象代理类实现切面编程效率会更高。
一般的切面编程,都用来增加日志,事务等,这个居多,当然也可以增加特殊的执行逻辑,大家可以动手试一下。