博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用codeigniter_使用CodeIgniter探索面向方面的编程,第3部分
阅读量:2511 次
发布时间:2019-05-11

本文共 9685 字,大约阅读时间需要 32 分钟。

使用codeigniter

In the previous parts of the series we learned about AOP concepts and the need for using AOP in large scale projects and I introduced CodeIgniter’s hooks as a convenient mechanism for creating AOP functionality from scratch. In this part I’ll show you how to use both XML and comment-based techniques to create custom AOP functionality when a dedicated AOP framework is not available.

在本系列的前几部分中,我们了解了AOP概念以及在大型项目中使用AOP的需求,我介绍了CodeIgniter的钩子作为从头开始创建AOP功能的便捷机制。 在这一部分中,我将向您展示在专用AOP框架不可用时如何使用XML和基于注释的技术来创建自定义AOP功能。

XML配置 (XML Configuration)

Let’s start with the XML method. First, we need a custom XML file with the AOP configuration details. I’m going to define specific tags for the AOP rules as shown in the code below.

让我们从XML方法开始。 首先,我们需要一个带有AOP配置详细信息的自定义XML文件。 我将为AOP规则定义特定的标签,如下面的代码所示。

Each AOP framework will have its own unique tags. Here I’ve defined <aopAspect> for each type of aspect and the <aopPointcut> tag to reduce the number of joinpoints to match certain criteria. In the <aopPointcut>, I’ve used the expression attribute which will be used to match the joinpoints.

每个AOP框架都有其自己的唯一标签。 在这里,我为每种类型的方面定义了<aopAspect><aopPointcut>标记,以减少符合特定条件的连接点数。 在<aopPointcut> ,我使用了expression属性,该属性将用于匹配连接点。

I’ve defined two tags for before and after advice; whenever a method matches the pointcut expression, it will look for before or after advice and call the methods provided in the Aspect class using the ref-class attribute value.

我为建议之前和之后定义了两个标签。 只要方法与切入点表达式匹配,它将在建议之前或之后进行查找,并使用ref-class属性值调用Aspect类中提供的方法。

In the above code, the expression [*.*] means the advice will be executed on all the methods of all the controllers. If we wanted to apply some advice to all of the delete methods. the pointcut expression would be [*.delete*]. If we wanted to apply advice to certain type of controllers, it would be [*Service.*]. You can define any custom structure to match classes and methods. The above is the just the most basic way of doing it.

在上面的代码中,表达式[*.*]表示建议将在所有控制器的所有方法上执行。 如果我们想对所有删除方法应用一些建议。 切入点表达式为[*.delete*] 。 如果我们想将建议应用于某些类型的控制器,则为[*Service.*] 。 您可以定义任何自定义结构以匹配类和方法。 上面是最基本的方法。

Now let’s look at how we can use this configuration file to apply advices in CodeIgniter. In the previous part I explained how to define pre_controller and post_controller hooks to call custom classes. The following shows the implementation of those classes.

现在让我们看看如何使用此配置文件在CodeIgniter中应用建议。 在上一部分中,我解释了如何定义pre_controllerpost_controller挂钩来调用自定义类。 下面显示了这些类的实现。

CI = &get_instance(); } public function applyBeforeAspects() { $uriSegments = $this->CI->uri->segment_array(); $controller = $uriSegments[1]; $function = $uriSegments[2]; $doc = new DOMDocument(); $doc->load("aop.xml"); $aopAspects = $doc->getElementsByTagName("aopPointcut"); foreach ($aopAspects as $aspect) { $expr = $aspect->getAttribute("expression"); preg_match('/[(.*?)]/s', $expr, $match); if (isset($match[1])) { $exprComponents = explode(".", $match[1]); $controllerExpr = "/^" . str_replace("*", "[a-zA-Z0-9]+", $exprComponents[0]) . "$/"; $functionExpr = "/^" . str_replace("*", "[a-zA-Z0-9]+", $exprComponents[1]) . "$/"; preg_match($controllerExpr, $controller, $controllerMatch); preg_match($functionExpr, $function, $functionMatch); if (count($controllerMatch) > 0 && count($functionMatch) > 0) { $beforeAspects = $aspect->getElementsByTagName("aopBefore"); foreach ($beforeAspects as $beforeAspect) { $refClass = $beforeAspect->getAttribute("ref-class"); $refMethod = $beforeAspect->getAttribute("method"); $classObject = new $refClass(); $classObject->$refMethod(); } } } } }}

All the code for before advices are applied inside the applyBeforeAspects() method.

之前建议的所有代码都应用在applyBeforeAspects()方法内部。

Initially we get the URI segments using CodeIgniter’s URI class. The first parameter is the controller and next parameter is the method name for the current request. Then we load our AOP configuration file using DOMDocument() and get the pointcuts using the <aopPointcut> tag.

最初,我们使用CodeIgniter的URI类获得URI段。 第一个参数是控制器,下一个参数是当前请求的方法名称。 然后,我们使用DOMDocument()加载AOP配置文件,并使用<aopPointcut>标记获取切入点。

While looping through each pointcut we get the expression attribute. Then we get the expression inside the brackets using regex and prepare the controller name and method name by exploding our matched string. I’ve used a basic regex to match the controllers and methods, but in a real AOP framework this would be much more complex.

在遍历每个切入点时,我们获得了expression属性。 然后,使用正则表达式将表达式放在括号内,并通过展开匹配的字符串来准备控制器名称和方法名称。 我使用了一个基本的正则表达式来匹配控制器和方法,但是在一个真正的AOP框架中,这将更加复杂。

Then we try to match the controller name and method name with the regular expressions we created. If both method and controller is matched, we have a poincut where we need to apply advices. Since we are applying before advice in this method, we get the <aopBefore> tags for the current pointcut. While looping through each before tag, we apply the advice by calling the method of ref-class.

然后,我们尝试将控制器名称和方法名称与我们创建的正则表达式进行匹配。 如果方法和控制器都匹配,则可以在其中应用建议。 由于我们在此方法之前应用建议,因此我们获得了当前切入点的<aopBefore>标记。 在遍历每个before标记时,我们通过调用ref-class的方法来应用建议。

This is a basic way of creating AOP functionality with CodeIgniter. The same process applies to after advice as well.

这是使用CodeIgniter创建AOP功能的基本方法。 同样的过程也适用于事后建议。

Our LoggingAspect class would resemble the following:

我们的LoggingAspect类类似于以下内容:

Now we have an idea how the XML method works, so let’s move on to the comment-based technique.

现在我们有了XML方法的工作原理,让我们继续进行基于注释的技术。

基于文档注释的配置 (Document Comment-Based Configuration)

In this technique we don’t have any configuration files as we did with the XML approach. Instead, all the advice is inside the aspect classes. We define comments according to a predefined structure and then we can manipulate the comments using PHP reflection classes to apply the advice.

在这种技术中,没有像XML方法那样的任何配置文件。 相反,所有建议都在方面类内部。 我们根据预定义的结构定义注释,然后可以使用PHP反射类操作注释以应用建议。

The LoggingAspect class has changed and is now an Aspect class using the @Aspect comment. At runtime, the AOP framework finds the aspect classes and looks for advice that matches specific pointcuts. Before and after advice is defined using @Before and @After and the specified execution parameter.

LoggingAspect类已更改,现在是使用@Aspect注释的Aspect类。 在运行时,AOP框架会找到方面类,并寻找与特定切入点匹配的建议。 使用@Before@After以及指定的执行参数定义通知之前和之后。

Let’s move onto the implementation for the applyBeforeAspects() function for this approach.

让我们继续此方法的applyBeforeAspects()函数的实现。

CI->uri->segment_array(); $controller = $uriSegments[1]; $function = $uriSegments[2]; $aspectClasses = array("LoggingAspect"); foreach ($aspectClasses as $aspectClass) { $ref = new ReflectionClass($aspectClass); $methods = $ref->getMethods(); foreach ($methods as $method) { $methodName = $method->name; $methodClass = $method->class; $reflectionMethod = new ReflectionMethod($methodClass, $methodName); $refMethodComment = $reflectionMethod->getDocComment(); preg_match('/@Before:execution[(.*?)]/s', $refMethodComment, $match); if (isset($match[1])) { $exprComponents = explode(".", $match[1]); $controllerExpr = "/^" . str_replace("*", "[a-zA-Z0-9]+", $exprComponents[0]) . "$/"; $functionExpr = "/^" . str_replace("*", "[a-zA-Z0-9]+", $exprComponents[1]) . "$/"; preg_match($controllerExpr, $controller, $controllerMatch); preg_match($functionExpr, $function, $functionMatch); if (count($controllerMatch) > 0 && count($functionMatch) > 0) { $classObject = new $methodClass(); $classObject->$methodName(); } } } }}

I’ve hard-coded the aspect class in an array for simplicity, but ideally all the aspect classes will be retrieved at runtime by the AOP framework.

为了简单起见,我已经将方面类硬编码在数组中,但是理想情况下,所有方面类都将在运行时由AOP框架检索。

We get the methods of each aspect class using reflection. Then, while looping through each method, we retrieve the document comment defined before the method. We extract the pointcut expression by matching the comment against a specific regular expression. Then we continue the same process as with the XML method for the remaining logic.

我们使用反射得到每个方面类的方法。 然后,在遍历每个方法的同时,我们检索在该方法之前定义的文档注释。 我们通过将注释与特定的正则表达式匹配来提取切入点表达式。 然后,对于其余的逻辑,我们继续使用与XML方法相同的过程。

摘要 (Summary)

During this series you learned about AOP concepts and how to identify situations where AOP should be applied. And while I hope you have a better understanding about how AOP works now, keep in mind CodeIgniter is not an AOP framework so using hooks will not be the most optimized way to apply AOP in your projects. Rather, CodeIgniter served as a vehicle throughout the series to provide knowledge about AOP from scratch so that you can easily adapt to any new AOP framework. I recommend you to use a well-known AOP framework for large scale projects since it might make your application more complex if not used wisely.

在本系列中,您学习了AOP概念以及如何确定应应用AOP的情况。 虽然我希望您对AOP现在的工作方式有更好的了解,但是请记住CodeIgniter并不是AOP框架,因此使用钩子并不是在项目中应用AOP的最优化方法。 而是,CodeIgniter在整个系列中充当工具,从头开始提供有关AOP的知识,以便您可以轻松地适应任何新的AOP框架。 我建议您对大型项目使用众所周知的AOP框架,因为如果使用不当,它可能会使您的应用程序更加复杂。

Image via

图片来自

翻译自:

使用codeigniter

转载地址:http://ahrgb.baihongyu.com/

你可能感兴趣的文章
APP版本号记录
查看>>
母函数
查看>>
最长不重复子串
查看>>
POJ 3621
查看>>
PHP ajax实现数组返回
查看>>
java web 自定义filter
查看>>
J.U.C Atomic(二)基本类型原子操作
查看>>
POJ---2945 Find the Clones[字典树-简单题(多例输入注意删除)]
查看>>
[Luogu4550] 收集邮票
查看>>
Python-循环
查看>>
(转)最大子序列和问题 看着貌似不错
查看>>
thinkphp3.2 链接数据库测试
查看>>
项目的上线流程是怎样的?
查看>>
Linux通配符
查看>>
ES6 Iterator
查看>>
Apache2.4开启GZIP功能
查看>>
远程桌面关闭重启电脑的方法
查看>>
第三章 熟悉常用的HDFS操作
查看>>
filter:expression(document.execCommand("BackgroundImageCache",false,true) 转
查看>>
Java - 30 Java 网络编程
查看>>