Home > php教程 > php手册 > php aop practice

php aop practice

WBOY
Release: 2016-07-09 09:10:01
Original
1555 people have browsed it

aop introduction

AOP is the abbreviation of Aspect Oriented Programming, which means: aspect-oriented programming (also called aspect-oriented). It can dynamically and uniformly add functions to the program without modifying the source code through pre-compilation and runtime dynamic agents. a technology. AOP is actually a continuation of the GoF design pattern. The design pattern tirelessly pursues the decoupling between the caller and the callee. AOP can be said to be a realization of this goal.

Introduction to aop-php

AOP-PHP is a PECL extension that allows you to use aspect-oriented programming in PHP without compiling or any other intermediate steps.

The design of AOP extension is the simplest method, you can think of aop implementation in PHP.

AOP is designed to allow separation of cross-cutting concerns (caching, logging, security, transactions,...)

Website: http://aop-php.github.io/

aop-php installation

Installation

There are two installation modes:

First method:

sudo pecl install aop-beta  
Copy after login

Second method:

<span>#</span><span>Clone the repository on your computer</span>
    git clone https://github.com/AOP-PHP/<span>AOP
    cd AOP
    </span><span>#</span><span>prepare the package, you will need to have development tools for php</span>
<span>    phpize
    </span><span>#</span><span>compile the package</span>
Copy after login
./configure --with-aop --with-php-config=/usr/bin/php-config
<span>
    make
    </span><span>#</span><span>before the installation, check that it works properly</span>
<span>    make test
    </span><span>#</span><span>install</span>
    make install
Copy after login

Error handling

The author made an error during the second method of installation (if there is no error, you can skip it here):

Can<span>'</span><span>t locate Autom4te/C4che.pm in @INC (@INC contains: /usr/local/share/autoconf...</span>
Copy after login

The solution is to reinstall autoconf:

<span>#</span><span>wget http://ftp.gnu.org/gnu/autoconf/autoconf-latest.tar.gz
#tar -zxf autoconf-latest.tar.gz
#rpm -qf /usr/bin/autoconf #查看autoconf的版本
#rpm -e --nodeps autoconf-2.59-12 #卸载原来版本
#./configure --prefix=/usr
#make && make install</span>
Copy after login

After successful compilation and installation, you need to load the module in php.ini. Generally, in centos, the php module is loaded in /etc/php.d. Create a new file aop.ini with the content:

extension=aop.so
Copy after login

After the installation is successful, check phpinfo and you will see the following content:

aop-php preschool preparation

Professional terminology

Before practicing, we need to learn some professional terms of haop.

Aspect: Horizontal aspect relationships are grouped into a class.
Advice (notification): used to call aspects and define what to do and when to do it under certain circumstances. Notifications are divided into: pre-notification, post-return notification, post-throw notification and peripheral notification.
Joinpoint: The location where notifications are created.
Pointcut: Defines a way to match notifications to certain access points.
For details, please refer to this blog: http://www.cnblogs.com/baochuan/archive/2012/08/22/2644529.html

Reference Document

After understanding this knowledge, we also need to download the aop-php documentation. Official document download
Okay, if you’re good at E-text, you can read the official document and skip directly to the text below.

Prepare documents

Before practice, we need to prepare four files: test function file testfunction.php, test class file testclass.php, test aop file testaop.php and run file test.php.

This can truly simulate our project. Most projects are laid out like this.

Aop-php practice notice

Notify before aop_add_before

Notifications used before some special points in the code, usually to call a method or function.

Let’s test the function first

testfunction.php code:

<?<span>php
</span><span>function</span><span> testFunc1(){
    </span><span>echo</span> 'aop_add_before <br/>'<span>;
}</span>
Copy after login

testaop.php code:

<?<span>php
</span><span>$testpoint1</span> = <span>function</span><span> () {
</span><span>echo</span> "这是前切点测试函数:"<span>;
};
aop_add_before(</span>'testFunc1()', <span>$testpoint1</span>);
Copy after login

test.php code:

<?<span>php
</span><span>require</span> 'testaop.php'<span>;
</span><span>require</span> 'testclass.php'<span>;
</span><span>require</span> 'testfunction.php'<span>;
</span><span>header</span>("Content-Type:text/html;charset=utf-8"<span>); 
testFunc1();</span>
Copy after login

No surprise, when we execute test.php we will see:

这是前切点测试函数:aop_add_before 
Copy after login

Let’s play Kazakhstan again

testclass.php code:

<?<span>php
</span><span>class</span><span> testClass1
{
    </span><span>public</span> <span>function</span><span> testBeforAdd1()
    {
        </span><span>echo</span> <span>get_class</span>(<span>$this</span><span>);
    }
}</span>
Copy after login

testaop.php code:

<?<span>php
</span><span>$testpoint1</span> = <span>function</span><span> () {
</span><span>echo</span> "这是前切点测试函数:"<span>;
};
</span><span>$testpoint2</span> = <span>function</span><span> () {
</span><span>echo</span> "这是前切点测试类方法:"<span>;
};
aop_add_before(</span>'testFunc1()', <span>$testpoint1</span><span>);
aop_add_before(</span>'testClass1->testBeforAdd1()', <span>$testpoint2</span>);
Copy after login

test.php code:

<?<span>php
</span><span>require</span> 'testaop.php'<span>;
</span><span>require</span> 'testclass.php'<span>;
</span><span>require</span> 'testfunction.php'<span>;
</span><span>header</span>("Content-Type:text/html;charset=utf-8"<span>); 
testFunc1();
</span><span>$testClass1</span> = <span>new</span><span> testClass1();
</span><span>echo</span> <span>$testClass1</span>->testBeforAdd1();
Copy after login

Execute test.php

这是前切点测试函数:aop_add_before 
这是前切点测试类方法:testClass1
Copy after login

Test class attributes again

testclass.php source code

<?<span style="color: #000000;">php
</span><span style="color: #008000;">//</span><span style="color: #008000;">测试前通知类</span>
<span style="color: #0000ff;">class</span><span style="color: #000000;"> testClass1
{
    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> function testBeforAdd1()
    {
        echo get_class($</span><span style="color: #0000ff;">this</span>) .<span style="color: #800000;">'</span><span style="color: #800000;"><br /></span><span style="color: #800000;">'</span><span style="color: #000000;">;
    }        
}
</span><span style="color: #008000;">//</span><span style="color: #008000;">测试前通知类属性</span>
<span style="color: #0000ff;">class</span><span style="color: #000000;"> testClass2
{
    </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> $name;
    </span><span style="color: #0000ff;">public</span> $publicProperty1 = <span style="color: #800000;">'</span><span style="color: #800000;">test</span><span style="color: #800000;">'</span><span style="color: #000000;">;
    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> function __construct ($name)
    {
        $</span><span style="color: #0000ff;">this</span>->name =<span style="color: #000000;"> $name;
    }
    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> function getName ()
    {
        </span><span style="color: #0000ff;">return</span> $<span style="color: #0000ff;">this</span>-><span style="color: #000000;">name;
    }
    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> function test ()
    {
        $</span><span style="color: #0000ff;">this</span>->publicProperty1 = <span style="color: #800000;">'</span><span style="color: #800000;">test</span><span style="color: #800000;">'</span><span style="color: #000000;">;
        </span><span style="color: #0000ff;">return</span> $<span style="color: #0000ff;">this</span>-><span style="color: #000000;">publicProperty1;
    }
        
}</span>
Copy after login

testaop.php source code

<?<span style="color: #000000;">php
</span><span style="color: #800080;">$testpoint11</span> = <span style="color: #0000ff;">function</span><span style="color: #000000;">  ()
{
    </span><span style="color: #0000ff;">echo</span> "这是前切点测试函数:"<span style="color: #000000;">;
};
</span><span style="color: #800080;">$testpoint12</span> = <span style="color: #0000ff;">function</span><span style="color: #000000;">  ()
{
    </span><span style="color: #0000ff;">echo</span> "这是前切点测试类方法:"<span style="color: #000000;">;
};
aop_add_before(</span>'testFunc1()', <span style="color: #800080;">$testpoint11</span><span style="color: #000000;">);
aop_add_before(</span>'testClass1->testBeforAdd1()', <span style="color: #800080;">$testpoint12</span><span style="color: #000000;">);
</span><span style="color: #008000;">//</span><span style="color: #008000;">------测试类属性</span>
<span style="color: #0000ff;">class</span><span style="color: #000000;"> changeProperty
{
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> shoot ( <span style="color: #800080;">$who</span>, <span style="color: #800080;">$what</span><span style="color: #000000;">)
    {
        </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$what</span> == 'test'<span style="color: #000000;">){
            </span><span style="color: #800080;">$what</span> = '测试前通知类属性截取 <br/>'<span style="color: #000000;">;
        }
        </span><span style="color: #0000ff;">echo</span> "<span style="color: #800080;">$who</span> 想要 <span style="color: #800080;">$what</span> "<span style="color: #000000;">;
    }
}
</span><span style="color: #800080;">$testclass1</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> changeProperty();
</span><span style="color: #800080;">$testpoint2</span> = <span style="color: #0000ff;">function</span>  ( AopJoinPoint <span style="color: #800080;">$aop_tjp</span> ) <span style="color: #0000ff;">use</span>( <span style="color: #800080;">$testclass1</span><span style="color: #000000;"> )
{
    </span><span style="color: #0000ff;">if</span> ( <span style="color: #800080;">$aop_tjp</span>->getKindOfAdvice() ===<span style="color: #000000;"> AOP_KIND_BEFORE_READ_PROPERTY )
    {
        </span><span style="color: #0000ff;">return</span>; <span style="color: #008000;">//</span><span style="color: #008000;"> 如果属性不能读则返回</span>
<span style="color: #000000;">    }
    </span><span style="color: #0000ff;">elseif</span> ( <span style="color: #800080;">$aop_tjp</span>->getKindOfAdvice() ===<span style="color: #000000;"> AOP_KIND_BEFORE_WRITE_PROPERTY )
    {
        </span><span style="color: #800080;">$testclass1</span>->shoot(<span style="color: #800080;">$aop_tjp</span>->getObject()->getName(),<span style="color: #800080;">$aop_tjp</span>-><span style="color: #000000;">getAssignedValue());
    }
};
</span><span style="color: #008000;">//</span><span style="color: #008000;">测试类属性</span>
aop_add_before('testClass2->publicProperty1', <span style="color: #800080;">$testpoint2</span>);
Copy after login

test.php source code

<?<span style="color: #000000;">php
</span><span style="color: #0000ff;">require</span> 'testaop.php'<span style="color: #000000;">;
</span><span style="color: #0000ff;">require</span> 'testclass.php'<span style="color: #000000;">;
</span><span style="color: #0000ff;">require</span> 'testfunction.php'<span style="color: #000000;">;
</span><span style="color: #008080;">header</span>("Content-Type:text/html;charset=utf-8"<span style="color: #000000;">); 
</span><span style="color: #008000;">//</span><span style="color: #008000;">前通知</span>
<span style="color: #000000;">testFunc1();
</span><span style="color: #800080;">$testClass1</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> testClass1();
</span><span style="color: #0000ff;">echo</span> <span style="color: #800080;">$testClass1</span>-><span style="color: #000000;">testBeforAdd1();
</span><span style="color: #800080;">$runtest2</span> = <span style="color: #0000ff;">new</span> testClass2('skyboy'<span style="color: #000000;">);
</span><span style="color: #800080;">$runtest2</span>->test();
Copy after login

Execute test.php

这是前切点测试函数:aop_add_before 
这是前切点测试类方法:testClass1
skyboy 想要 测试前通知类属性截取 
Copy after login

Notify aop_add_after after return

Notifications used after some special points in the code, usually by calling a method or function.

Test function

testfunction.php source code:

<span style="color: #0000ff;">function</span><span style="color: #000000;"> testFunc2(){
    </span><span style="color: #0000ff;">echo</span> '这是返回后通知测试:'<span style="color: #000000;">;
}</span>
Copy after login

testaop.php源码:

<span style="color: #008000;">//</span><span style="color: #008000;">测试返回后通知</span>
<span style="color: #800080;">$testpoint22</span> = <span style="color: #0000ff;">function</span><span style="color: #000000;">  ()
{
    </span><span style="color: #0000ff;">echo</span> "aop_add_after <br/>"<span style="color: #000000;">;
};
aop_add_after(</span>'testFunc2()', <span style="color: #800080;">$testpoint22</span>);
Copy after login

test.php源码:

<span style="color: #008000;">//</span><span style="color: #008000;">后通知</span>
testFunc2();
Copy after login

 

执行test.php

这是返回后通知测试:aop_add_after
Copy after login

  

类和类属性和前通知类似,为了节省篇幅,这里偷懒了。

 

周边通知aop_add_around 

测试函数

testfunction.php源码:

<span style="color: #0000ff;">function</span> testFunc3(<span style="color: #800080;">$param1</span>,<span style="color: #800080;">$param2</span><span style="color: #000000;">){
    </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$param1</span>. <span style="color: #800080;">$param2</span><span style="color: #000000;">;
}</span>
Copy after login

 

testaop.php源码:

<span style="color: #008000;">//</span><span style="color: #008000;">测试周边通知</span>

<span style="color: #0000ff;">function</span> testaround (AopJoinPoint <span style="color: #800080;">$object</span><span style="color: #000000;">)
{
    </span><span style="color: #800080;">$args</span> = <span style="color: #800080;">$object</span>-><span style="color: #000000;">getArguments();
    </span><span style="color: #0000ff;">if</span> (<span style="color: #800080;">$args</span>[0] !== <span style="color: #0000ff;">null</span><span style="color: #000000;">) {
        </span><span style="color: #800080;">$args</span>[0] = '我想测试'<span style="color: #000000;">;
    }
    </span><span style="color: #0000ff;">if</span> (<span style="color: #800080;">$args</span>[1] !== <span style="color: #0000ff;">null</span><span style="color: #000000;">) {
        </span><span style="color: #800080;">$args</span>[1] = '周边通知:'<span style="color: #000000;">;
    }
    </span><span style="color: #800080;">$object</span>->setArguments(<span style="color: #800080;">$args</span><span style="color: #000000;">);
    </span><span style="color: #800080;">$object</span>-><span style="color: #000000;">process();
    
    </span><span style="color: #800080;">$returnValue</span> = <span style="color: #800080;">$object</span>-><span style="color: #000000;">getReturnedValue();
    </span><span style="color: #800080;">$returnValue</span> .= 'aop_add_around<br/>'<span style="color: #000000;">;
    </span><span style="color: #800080;">$object</span>->setReturnedValue(<span style="color: #800080;">$returnValue</span><span style="color: #000000;">);
    
}
aop_add_around(</span>'testFunc3()', 'testaround');
Copy after login

 

test.php源码:

<span style="color: #008000;">//</span><span style="color: #008000;">周边通知</span>
<span style="color: #0000ff;">echo</span> testFunc3(1,2);
Copy after login

 

执行test.php

我想测试周边通知:aop_add_around
Copy after login

 

 

类和类属性和前通知类似。

 

aop-php函数说明

除了三个重要函数aop_add_before,aop_add_after,aop_add_around之外,我们还要记住这几个重要的函数。

getKindOfAdvice

获取通知的类型。有以下几个默认值。一般用在方法的属性更改。

• AOP_KIND_BEFORE before a given call, may it be function, method or property
• AOP_KIND_BEFORE_METHOD before a method call (method of an object)
• AOP_KIND_BEFORE_FUNCTION before a function call (not a method call)
• AOP_KIND_BEFORE_PROPERTY before a property (read or write)
• AOP_KIND_BEFORE_READ_PROPERTY before a property access (read only)
• AOP_KIND_BEFORE_WRITE_PROPERTY before a property write (write only)
• AOP_KIND_AROUND around a given call, may it be function, method or property access (read / write)
• AOP_KIND_AROUND_METHOD around a method call (method of an object)
• AOP_KIND_AROUND_FUNCTION around a function call (not a method call)
• AOP_KIND_AROUND_PROPERTY around a property (read or write)
• AOP_KIND_AROUND_READ_PROPERTY around a property access (read only)
• AOP_KIND_AROUND_WRITE_PROPERTY around a property write (write only)
• AOP_KIND_AFTER after a given call, may it be function, method or property access (read / write)
• AOP_KIND_AFTER_METHOD after a method call (method of an object)
• AOP_KIND_AFTER_FUNCTION after a function call (not a method call)
• AOP_KIND_AFTER_PROPERTY after a property (read or write)
• AOP_KIND_AFTER_READ_PROPERTY after a property access (read only)
• AOP_KIND_AFTER_WRITE_PROPERTY after a property write (write only)

getArguments

获取方法的参数。一般用在aop_add_before/aop_add_around。

setArguments

设置方法的参数。一般用在aop_add_before/aop_add_around。

getReturnedValue

获取方法的返回值。一般用在aop_add_after/aop_add_around。

setReturnedValue

设置方法的返回值。一般用在aop_add_after/aop_add_around。

process

让方法运行。一般用在aop_add_around。

 

具体详细说明,请参考官方文档。

 

aop-php开启和关闭

新建一个文件aopopenclose.php

源码如下:

<?<span style="color: #000000;">php
</span><span style="color: #008080;">ini_set</span>("aop.enable", "1"<span style="color: #000000;">);
</span><span style="color: #0000ff;">echo</span> "aop is enabled<br />"<span style="color: #000000;">;
</span><span style="color: #0000ff;">function</span><span style="color: #000000;"> foo ()
{
    </span><span style="color: #0000ff;">echo</span> "I'm foo<br />"<span style="color: #000000;">;
}
</span><span style="color: #800080;">$adviceShowFoo</span> = <span style="color: #0000ff;">function</span><span style="color: #000000;">  ()
{
    </span><span style="color: #0000ff;">echo</span> "After foo<br />"<span style="color: #000000;">;
};
aop_add_after(</span>'foo()', <span style="color: #800080;">$adviceShowFoo</span><span style="color: #000000;">);
foo();
</span><span style="color: #008080;">ini_set</span>('aop.enable', '0'<span style="color: #000000;">);
</span><span style="color: #0000ff;">echo</span> "aop is now disabled<br />"<span style="color: #000000;">;
foo();
</span><span style="color: #0000ff;">echo</span> "But you can still register new aspects<br />"<span style="color: #000000;">;
aop_add_after(</span>'f*()', <span style="color: #800080;">$adviceShowFoo</span><span style="color: #000000;">);
foo();
</span><span style="color: #008080;">ini_set</span>('aop.enable', '1'<span style="color: #000000;">);
</span><span style="color: #0000ff;">echo</span> "Aop is now enabled<br />"<span style="color: #000000;">;
foo();</span>
Copy after login

 

运行结果:

aop is enabled
I'm foo
After foo
aop is now disabled
I'm foo
After foo
But you can still register new aspects
I'm foo
After foo
After foo
Aop is now enabled
I'm foo
After foo
After foo
Copy after login

  

aop-php总结

aop-php在真实意义上实现了php的aop,用户无需用其他的方式即可轻松实现。aop的编程思想是一把利刃,可以让耦合性差的项目轻松实现解耦。

全部测试文件和编辑后文件打包。点此下载。(基于ceotos环境php5.3编译)

 

 

 
 
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Recommendations
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template