├── .gitignore
├── .travis.yml
├── CHANGELOG
├── CREDITS
├── EXPERIMENTAL
├── LICENSE
├── Lexer.c
├── Lexer.h
├── Lexer.l
├── README.md
├── RELEASE-0.1.0
├── RELEASE-0.2.0
├── RELEASE-0.2.1b5
├── RELEASE-0.2.2b1
├── THANKS
├── aop.c
├── aop.h
├── aop_joinpoint.c
├── aop_joinpoint.h
├── config.m4
├── config.w32
├── doc
├── Contents
│ ├── chapter1.md
│ ├── chapter2.md
│ └── chapter3.md
├── aop.php
├── config.yml
└── php-declaration-generator.php
├── package.xml
├── phpdoc
├── aopjoinpoint
│ ├── getarguments.xml
│ ├── getassignedvalue.xml
│ ├── getclassname.xml
│ ├── getfunctionname.xml
│ ├── getkindofadvice.xml
│ ├── getmethodname.xml
│ ├── getobject.xml
│ ├── getpointcut.xml
│ ├── getpropertyname.xml
│ ├── getreturnedvalue.xml
│ ├── process.xml
│ ├── setarguments.xml
│ ├── setassignedvalue.xml
│ └── setreturnedvalue.xml
├── aoptriggeredjoinpoint.xml
├── book.developer.xml
├── book.xml
├── configure.xml
├── constants.xml
├── entities.aopjoinpoint.xml
├── entities.functions.xml
├── functions
│ ├── aop-add-after.xml
│ ├── aop-add-around.xml
│ └── aop-add-before.xml
├── pointcut.xml
├── reference.xml
├── setup.xml
└── versions.xml
├── phpunit.xml.dist
└── tests
├── after_returning
└── 001.phpt
├── after_throwing
└── 001.phpt
├── arguments_overload
├── 001.phpt
└── 002.phpt
├── articles
└── 001.phpt
├── autoload
└── 001.phpt
├── bugs
├── 001.phpt
├── 002.phpt
├── 003.phpt
├── 004.phpt
├── 005.phpt
├── 006.phpt
└── 007.phpt
├── cache
├── 001.phpt
├── 002.phpt
└── 003.phpt
├── complete
└── 001.phpt
├── consts
├── 001.phpt
├── 002.phpt
├── 003.phpt
└── 004.phpt
├── context
├── 001.phpt
└── 002.phpt
├── docsexample
├── 0.phpt
├── 001.phpt
├── 002.phpt
├── 003.phpt
├── 1.phpt
├── 10.phpt
├── 11.phpt
├── 12.phpt
├── 13.phpt
├── 14.phpt
├── 15.phpt
├── 16.phpt
├── 17.phpt
├── 18.phpt
├── 19.phpt
├── 2.phpt
├── 21.phpt
├── 22.phpt
├── 23.phpt
├── 24.phpt
├── 25.phpt
├── 3.phpt
├── 4.phpt
├── 5.phpt
├── 6.phpt
├── 7.phpt
├── 8.phpt
└── 9.phpt
├── exception
└── 001.phpt
├── getargs
├── 001.phpt
└── 002.phpt
├── getthis
├── 001.phpt
└── 002.phpt
├── inheritance
├── 001.phpt
├── 002.phpt
├── 003.phpt
├── 005.phpt
├── 006.phpt
└── 007.phpt
├── ini_directives
└── 001.phpt
├── issues
├── 001.phpt
├── 002.phpt
├── 003.phpt
├── 004.phpt
├── 005.phpt
├── 006.phpt
├── 007.phpt
├── 008.phpt
├── 009.phpt
├── 010.phpt
├── 011.phpt
├── 47.phpt
├── 47_2.phpt
├── 52.phpt
├── 52_2.phpt
├── 65.phpt
└── 65_2.phpt
├── joker
├── 001.phpt
├── 002.phpt
├── 003.phpt
├── 004.phpt
├── 005.phpt
├── 006.phpt
├── 007.phpt
├── 008.phpt
└── 009.phpt
├── keywords
├── 001.phpt
├── 002.phpt
├── 003.phpt
├── empty.php
├── empty_2.php
├── empty_3.php
└── empty_4.php
├── misc
├── 001.phpt
├── 002.phpt
└── 003.phpt
├── ns
└── 001.phpt
├── properties
├── 001.phpt
├── 002.phpt
├── 003.phpt
├── 004.phpt
├── 005.phpt
├── 006.phpt
├── 007.phpt
├── 008.phpt
├── 009.phpt
└── 010.phpt
├── read_properties
├── 001.phpt
└── 003.phpt
├── scope
├── 001.phpt
├── 002.phpt
└── 003.phpt
├── simple
├── 001.phpt
├── 002.phpt
├── 003.phpt
├── 004.phpt
├── 005.phpt
├── 006.phpt
├── 007.phpt
├── 008.phpt
└── 009.phpt
├── traits
└── 001.phpt
└── write_properties
├── 001.phpt
├── 002.phpt
├── 003.phpt
├── 004.phpt
├── 005.phpt
├── 006.phpt
└── 007.phpt
/.gitignore:
--------------------------------------------------------------------------------
1 | .libs/
2 | Makefile
3 | Makefile.fragments
4 | Makefile.global
5 | Makefile.objects
6 | acinclude.m4
7 | aclocal.m4
8 | autom4te.cache/
9 | build/
10 | config.guess
11 | config.h
12 | config.h.in
13 | config.log
14 | config.nice
15 | config.status
16 | config.sub
17 | configure
18 | configure.in
19 | install-sh
20 | libtool
21 | ltmain.sh
22 | missing
23 | mkinstalldirs
24 | modules/
25 | *.la
26 | *.lo
27 | run-tests.php
28 | tests/*/*.diff
29 | tests/*/*.exp
30 | tests/*/*.log
31 | tests/*/*.out
32 | tests/*/*.php
33 | tests/*/*.sh
34 | .deps
35 | *.swp
36 | *~
37 | Debug/
38 | *.opensdf
39 | *.sdf
40 | *.sln
41 | *.v11.suo
42 | *.vcxproj
43 | *.vcxproj.filters
44 | .cproject
45 | .project
46 | tags
47 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | php:
4 | # We only specify one version so we only get one worker
5 | - 5.3
6 | - 5.4
7 | - 5.5
8 |
9 | before_script:
10 | - phpize && ./configure && make && sudo make install
11 | - echo "extension=aop.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
12 |
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
1 | 0.3
2 | getPointcutValue
3 | 0.2
4 | AopTriggeredJoinPoint was renamed AopJoinPoint
5 | AopJoinPoint->getTriggering* was renamed AopJoinPoint->get*
6 | Updated error messages to be more explicit
7 | lots of bug fixes
8 | performances improvements
9 |
10 | 0.1
11 | First Beta
12 |
--------------------------------------------------------------------------------
/CREDITS:
--------------------------------------------------------------------------------
1 | Julien Salleyron
2 | Gérald Croës
3 |
--------------------------------------------------------------------------------
/EXPERIMENTAL:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | --------------------------------------------------------------------
2 | The PHP License, version 3.01
3 | Copyright (c) 1999 - 2012 The PHP Group. All rights reserved.
4 | --------------------------------------------------------------------
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, is permitted provided that the following conditions
8 | are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright
11 | notice, this list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright
14 | notice, this list of conditions and the following disclaimer in
15 | the documentation and/or other materials provided with the
16 | distribution.
17 |
18 | 3. The name "PHP" must not be used to endorse or promote products
19 | derived from this software without prior written permission. For
20 | written permission, please contact group@php.net.
21 |
22 | 4. Products derived from this software may not be called "PHP", nor
23 | may "PHP" appear in their name, without prior written permission
24 | from group@php.net. You may indicate that your software works in
25 | conjunction with PHP by saying "Foo for PHP" instead of calling
26 | it "PHP Foo" or "phpfoo"
27 |
28 | 5. The PHP Group may publish revised and/or new versions of the
29 | license from time to time. Each version will be given a
30 | distinguishing version number.
31 | Once covered code has been published under a particular version
32 | of the license, you may always continue to use it under the terms
33 | of that version. You may also choose to use such covered code
34 | under the terms of any subsequent version of the license
35 | published by the PHP Group. No one other than the PHP Group has
36 | the right to modify the terms applicable to covered code created
37 | under this License.
38 |
39 | 6. Redistributions of any form whatsoever must retain the following
40 | acknowledgment:
41 | "This product includes PHP software, freely available from
42 | ".
43 |
44 | THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
45 | ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
46 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
47 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
48 | DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
49 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
51 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
53 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
55 | OF THE POSSIBILITY OF SUCH DAMAGE.
56 |
57 | --------------------------------------------------------------------
58 |
59 | This software consists of voluntary contributions made by many
60 | individuals on behalf of the PHP Group.
61 |
62 | The PHP Group can be contacted via Email at group@php.net.
63 |
64 | For more information on the PHP Group and the PHP project,
65 | please see .
66 |
67 | PHP includes the Zend Engine, freely available at
68 | .
69 |
--------------------------------------------------------------------------------
/Lexer.h:
--------------------------------------------------------------------------------
1 | //--------------------------------------------------------- ./scanner.h
2 |
3 | #ifndef _LEXER_H
4 | # define _LEXER_H
5 | #define SCANNER_RETCODE_EOF -1
6 | #define SCANNER_RETCODE_ERR -2
7 | #define SCANNER_RETCODE_IMPOSSIBLE -3
8 |
9 | #define TOKEN_SPACE 0
10 | #define TOKEN_FUNCTION 1
11 | #define TOKEN_CLASS 2
12 | #define TOKEN_JOKER 3
13 | #define TOKEN_SUPER_JOKER 4
14 | #define TOKEN_PROPERTY 5
15 | #define TOKEN_SCOPE 6
16 | #define TOKEN_STATIC 7
17 | #define TOKEN_OR 8
18 | #define TOKEN_TEXT 9
19 |
20 |
21 | typedef struct _scanner_state {
22 | char* start;
23 | char* end;
24 | char* marker;
25 | } scanner_state;
26 |
27 | typedef struct _scanner_token {
28 | int TOKEN;
29 | char *str_val;
30 | int int_val;
31 |
32 | } scanner_token;
33 |
34 | int scan(scanner_state *state, scanner_token *token);
35 | //TODO: some functions to manipulate scanner states
36 |
37 | #endif
38 |
--------------------------------------------------------------------------------
/Lexer.l:
--------------------------------------------------------------------------------
1 | //--------------------------------------------------------- ./scanner.l
2 |
3 | #include
4 | #include "Lexer.h"
5 | #include "ext/pcre/php_pcre.h"
6 | #include "aop.h"
7 |
8 | int scan(scanner_state *s, scanner_token *t) {
9 |
10 | // char *cursor = s->start;
11 | int r=SCANNER_RETCODE_IMPOSSIBLE;
12 | char *q=s->start;//keep initial start
13 |
14 | #define YYCTYPE char
15 | #define YYCURSOR (s->start)
16 | #define YYLIMIT (s->end)
17 | #define YYMARKER (s->marker)
18 |
19 | while(SCANNER_RETCODE_IMPOSSIBLE == r) {
20 |
21 | /*!re2c
22 | re2c:indent:top = 2;
23 | re2c:yyfill:enable = 0;
24 | LABEL = [a-zA-Z0-9_\x7f-\xff\\*]*;
25 | SPACE = [ \t$]*;
26 | '()' {
27 | t->TOKEN = TOKEN_FUNCTION;
28 | return 0;
29 | }
30 | '->' {
31 | t->TOKEN = TOKEN_CLASS;
32 | return 0;
33 | }
34 | '::' {
35 | t->TOKEN = TOKEN_CLASS;
36 | return 0;
37 | }
38 | 'read' {
39 | t->TOKEN = TOKEN_PROPERTY;
40 | t->int_val = AOP_KIND_READ;
41 | return 0;
42 | }
43 | 'write' {
44 | t->TOKEN = TOKEN_PROPERTY;
45 | t->int_val = AOP_KIND_WRITE;
46 | return 0;
47 | }
48 | 'public' {
49 | t->TOKEN = TOKEN_SCOPE;
50 | t->int_val = ZEND_ACC_PUBLIC;
51 | return 0;
52 | }
53 | 'protected' {
54 | t->TOKEN = TOKEN_SCOPE;
55 | t->int_val = ZEND_ACC_PROTECTED;
56 | return 0;
57 | }
58 | 'private' {
59 | t->TOKEN = TOKEN_SCOPE;
60 | t->int_val = ZEND_ACC_PRIVATE;
61 | return 0;
62 | }
63 | 'static' {
64 | t->TOKEN = TOKEN_STATIC;
65 | t->int_val = 1;
66 | return 0;
67 | }
68 | "|" {
69 | t->TOKEN = TOKEN_OR;
70 | return 0;
71 | }
72 | '!public' {
73 | t->TOKEN = TOKEN_SCOPE;
74 | t->int_val = ZEND_ACC_PROTECTED | ZEND_ACC_PRIVATE;
75 | return 0;
76 | }
77 | '!protected' {
78 | t->TOKEN = TOKEN_SCOPE;
79 | t->int_val = ZEND_ACC_PUBLIC | ZEND_ACC_PRIVATE;
80 | return 0;
81 | }
82 | '!private' {
83 | t->TOKEN = TOKEN_SCOPE;
84 | t->int_val = ZEND_ACC_PUBLIC | ZEND_ACC_PROTECTED;
85 | return 0;
86 | }
87 | '!static' {
88 | t->TOKEN = TOKEN_STATIC;
89 | t->int_val = 0;
90 | return 0;
91 | }
92 | LABEL {
93 | t->str_val = estrndup(q,YYCURSOR - q);
94 | t->TOKEN = TOKEN_TEXT;
95 | return 0;
96 | }
97 | SPACE {
98 | t->TOKEN = TOKEN_SPACE;
99 | return 0;
100 | }
101 | "\000" { r = SCANNER_RETCODE_EOF; break; }
102 |
103 | [^] { r = SCANNER_RETCODE_ERR; break; }
104 | */
105 | }
106 | return r;
107 | }
108 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Introduction #
2 |
3 | AOP is a PECL extension that enables you to use Aspect Oriented Programming in PHP, without the need
4 | to compile or proceed to any other intermediate step before publishing your code.
5 |
6 | The AOP extension is designed to be the easiest way you can think of for integrating AOP to PHP.
7 |
8 | AOP aims to allow separation of cross-cutting concerns (cache, log, security, transactions, ...)
9 |
10 | [](http://travis-ci.org/AOP-PHP/AOP)
11 |
12 | ## Installation ##
13 |
14 | You can use pecl
15 |
16 | ```sh
17 | sudo pecl install aop-beta
18 | ```
19 |
20 | or
21 |
22 | Download the AOP from github, compile and add the extension to your php.ini
23 |
24 | ```sh
25 | #Clone the repository on your computer
26 | git clone https://github.com/AOP-PHP/AOP
27 | cd AOP
28 | #prepare the package, you will need to have development tools for php
29 | phpize
30 | #compile the package
31 | ./configure
32 | make
33 | #before the installation, check that it works properly
34 | make test
35 | #install
36 | make install
37 | ```
38 |
39 | Now you can add the following line to your php.ini to enables AOP
40 |
41 | ```ini
42 | extension=AOP.so
43 | ```
44 |
45 | ## What is AOP ? Basic tutorial ##
46 |
47 | Let's assume the following class
48 |
49 | ``` php
50 | doAdmin*()', 'adviceForDoAdmin');
104 | ```
105 |
106 | Now, each time you'll invoke a method of an object of the class MyServices, starting by doAdmin, AOP will launch the function
107 | basicAdminChecker *before* the called method.
108 |
109 | That's it, simple ain't it ?
110 |
111 | Now le's try the examples :
112 |
113 | ``` php
114 | doAdminStuff1();//will raise an exception as nothing in the current session tells us we are an admin
120 | } catch (Exception $e) {
121 | echo "You cannot access the service, you're not an admin";
122 | }
123 |
124 | $_SESSION['user_type'] = 'admin';//again, this is ugly for the sake of the example
125 |
126 | try {
127 | $service->doAdminStuff1();
128 | $service->doAdminStuff2();
129 | } catch (Exception $e) {
130 | //nothing will be caught here, we are an admin
131 | }
132 | ```
133 |
134 | Here you are, you know the basics of AOP.
135 |
136 | ## AOP Vocabulary and PHP's AOP capabilities ##
137 |
138 | ### Advice ###
139 |
140 | An advice is a piece of code that can be executed. In our first example, the function adviceForAdmin is an advice, it
141 | *could* be executed.
142 |
143 | In PHP's AOP extension, an advice can be a trait, a callback, an anonymous function, a static method of a class,
144 | a method of a given object or a closure.
145 |
146 | ### Join points ###
147 |
148 | Join points are places where we can attach advices.
149 |
150 | In PHP's AOP extension, a join point can be:
151 |
152 | * before any method / function call
153 | * after any method / function call
154 | * around any method / function call
155 | * During the arousing of an exception of any method / function
156 | * after any method / function call, should the method terminate normally or not (triggers an exception or not)
157 |
158 | In our first example, we used a "before" join point.
159 |
160 | ### Pointcut ###
161 |
162 | Pointcuts are a way to describe whether or not a given join point will trigger the execution of an advice.
163 |
164 | In PHP's AOP extension, pointcuts can be configured with a quite simple and straightforward syntax.
165 |
166 | In our first example the pointcut was "MyServices->doAdmin*()" and was configured to launch the advice "before" the
167 | execution of the matching methods join points.
168 |
169 | ## Why or should I use AOP? ##
170 |
171 | AOP is a whole different way of thinking for developing application. It is as different as object oriented programming
172 | can be opposed to procedural programming.
173 |
174 | Event if you don't want to base your future development on this approach, you may find it very useful for debugging
175 | purposes. Imagine a world where you can debug or get informations on your code based on information only collected for
176 | a given user, a given context, a given procedure. A world where you can hunt weird and old code execution without even
177 | trying to update multiple and sparse PHP files, but just by adding advices on given conditions.
178 |
179 | We are sure that this extension will soon be part of your future development workflow!
180 |
181 | [Latest version of the documentation](http://www.croes.org/gerald/projects/aop/documentation_aop_extension_php.pdf)
182 |
--------------------------------------------------------------------------------
/RELEASE-0.1.0:
--------------------------------------------------------------------------------
1 | First Beta
2 |
--------------------------------------------------------------------------------
/RELEASE-0.2.0:
--------------------------------------------------------------------------------
1 | AopTriggeredJoinPoint was renamed AopJoinPoint
2 | AopJoinPoint->getTriggering* was renamed AopJoinPoint->get*
3 | Updated error messages to be more explicit
4 | lots of bug fixes
5 | performances improvements
6 |
--------------------------------------------------------------------------------
/RELEASE-0.2.1b5:
--------------------------------------------------------------------------------
1 | - Bugs on extract
2 | - Bugs on this in process()
3 |
--------------------------------------------------------------------------------
/RELEASE-0.2.2b1:
--------------------------------------------------------------------------------
1 | - Cache on function (With SegFault Correction)
2 |
--------------------------------------------------------------------------------
/THANKS:
--------------------------------------------------------------------------------
1 | stealth35 (Windows build)
2 |
--------------------------------------------------------------------------------
/aop_joinpoint.h:
--------------------------------------------------------------------------------
1 | /*
2 | /+----------------------------------------------------------------------+
3 | | AOP |
4 | +----------------------------------------------------------------------+
5 | | Copyright (c) 2012 Julien Salleyron, Gérald Croës |
6 | +----------------------------------------------------------------------+
7 | | This source file is subject to version 3.01 of the PHP license, |
8 | | that is bundled with this package in the file LICENSE, and is |
9 | | available through the world-wide-web at the following url: |
10 | | http://www.php.net/license/3_01.txt. |
11 | | If you did not receive a copy of the PHP license and are unable to |
12 | | obtain it through the world-wide-web, please send a note to |
13 | | license@php.net so we can mail you a copy immediately. |
14 | +----------------------------------------------------------------------+
15 | | Author: Julien Salleyron |
16 | +----------------------------------------------------------------------+
17 | */
18 | #ifndef PHP_AOP_JOINPOINT_H
19 | #define PHP_AOP_JOINPOINT_H 1
20 |
21 | PHP_METHOD(AopJoinpoint, getArguments);
22 | PHP_METHOD(AopJoinpoint, getPropertyName);
23 | PHP_METHOD(AopJoinpoint, getPropertyValue);
24 | PHP_METHOD(AopJoinpoint, setArguments);
25 | PHP_METHOD(AopJoinpoint, getKindOfAdvice);
26 | PHP_METHOD(AopJoinpoint, getReturnedValue);
27 | PHP_METHOD(AopJoinpoint, getAssignedValue);
28 | PHP_METHOD(AopJoinpoint, setReturnedValue);
29 | PHP_METHOD(AopJoinpoint, setAssignedValue);
30 | PHP_METHOD(AopJoinpoint, getPointcut);
31 | PHP_METHOD(AopJoinpoint, getObject);
32 | PHP_METHOD(AopJoinpoint, getClassName);
33 | PHP_METHOD(AopJoinpoint, getMethodName);
34 | PHP_METHOD(AopJoinpoint, getFunctionName);
35 | PHP_METHOD(AopJoinpoint, getException);
36 | PHP_METHOD(AopJoinpoint, process);
37 |
38 | #endif
39 |
--------------------------------------------------------------------------------
/config.m4:
--------------------------------------------------------------------------------
1 | PHP_ARG_ENABLE(AOP, whether to enable AOP support,
2 | [ --enable-AOP Enable AOP support])
3 |
4 | AC_MSG_CHECKING([for PCRE headers location])
5 | for i in /usr/include /usr/include/pcre /usr/local/include; do
6 | test -f $i/pcre.h && PCRE_INCDIR=$i
7 | done
8 |
9 | if test -z "$PCRE_INCDIR"; then
10 | AC_MSG_ERROR([Could not find pcre.h in $PHP_PCRE_REGEX])
11 | fi
12 | AC_MSG_RESULT([$PCRE_INCDIR])
13 |
14 | if test "$PHP_AOP" = "yes"; then
15 | AC_DEFINE(HAVE_AOP, 1, [aop])
16 | PHP_NEW_EXTENSION(aop, aop.c Lexer.c aop_joinpoint.c, $ext_shared)
17 | fi
18 |
--------------------------------------------------------------------------------
/config.w32:
--------------------------------------------------------------------------------
1 | ARG_ENABLE("aop", "Enable AOP support" , "no");
2 |
3 | if (PHP_AOP != "no") {
4 | EXTENSION("aop", "aop.c Lexer.c aop_joinpoint.c");
5 | }
6 |
--------------------------------------------------------------------------------
/doc/Contents/chapter1.md:
--------------------------------------------------------------------------------
1 | # Introduction #
2 |
3 | AOP is a PECL extension that enables you to use Aspect Oriented Programming in PHP, without the need
4 | to compile or proceed to any other intermediate step before publishing your code.
5 |
6 | The AOP extension is designed to be the easiest way you can think of for integrating AOP to PHP.
7 |
8 | AOP aims to allow separation of cross-cutting concerns (cache, log, security, transactions, ...)
9 |
10 | ## PHP's AOP extension history ##
11 |
12 | The AOP extension is a project which started a while ago even if its development is quite very new (early 2012). It was
13 | first expected to be a fully PHP developed library, as part of a dependency injection framework. The Aspect Oriented
14 | Programming implementation would have taken the form of auto generated proxies.
15 |
16 | That was before Julien Salleyron, the lead developer of the project, wanted to take it to the next level while writing
17 | the AOP core features as a PHP's extension.
18 |
19 | Gérald Croës also belongs to the initial team, mainly in charge of the documentation and discussions around
20 | the extension's API.
21 |
22 | ## Installation ##
23 |
24 | Download the AOP from github, compile and add the extension to your php.ini
25 |
26 | [bash]
27 | #Clone the repository on your computer
28 | git clone https://github.com/AOP-PHP/AOP
29 | cd AOP
30 | #prepare the package, you will need to have development tools for php
31 | phpize
32 | #compile the package
33 | ./configure
34 | make
35 | #before the installation, check that it works properly
36 | make test
37 | #install
38 | make install
39 |
40 | Now you can add the following line to your php.ini to enables AOP
41 |
42 | [ini]
43 | extension=aop.so
44 |
45 | ## What is AOP ? Basic tutorial ##
46 |
47 | Let's assume the following class
48 |
49 | [php]
50 | class MyServices
51 | {
52 | public function doAdminStuff1 ()
53 | {
54 | //some stuff only the admin should do
55 | echo "Calling doAdminStuff1";
56 | }
57 |
58 | public function doAdminStuff2 ()
59 | {
60 | //some stuff only the admin should do
61 | echo "Calling doAdminStuff2";
62 | }
63 | }
64 |
65 | Now you want your code to be safe, you don't want non admin users to be able to call doAdminMethods.
66 |
67 | What are your solutions ?
68 |
69 | * Add some code to check the credentials "IN" you MyServices class. The drawback is that it will pollute your
70 | code, and your core service will be less readable.
71 | * Let the clients have the responsibility to check the credentials when required. The drawbacks are that you will
72 | duplicate lots of code client side if you have to call the service from multiple places
73 | * Add some kind of credential proxy that will check the credentials before calling the actual service. The drawbacks
74 | are that you will have to write some extra code, adding another class on the top of your services.
75 |
76 | Moreover, these solutions tend to increase in complexity while you are adding more cross-cutting concerns like
77 | caching or logging.
78 |
79 | That's where AOP comes into action as you will be able to tell PHP to do some extra actions while calling your
80 | MyServices's admin methods.
81 |
82 | So let's first write the rule needed to check if we can or cannot access the admin services.
83 |
84 | [php]
85 | function adviceForDoAdmin ()
86 | {
87 | if ((! isset($_SESSION['user_type'])) || ($_SESSION['user_type'] !== 'admin')) {
88 | throw new Exception('Sorry, you should be an admin to do this');
89 | }
90 | }
91 |
92 | Dead simple : we check the current PHP session to see if there is something telling us the current user is an admin (of
93 | course we do realize that you may have more complex routines to do that, but we'll keep this for the example).
94 |
95 | Now, let's use AOP to tell PHP to execute this method "before" any execution of admin methods.
96 |
97 | [php]
98 | aop_add_before('MyServices->doAdmin*()', 'adviceForDoAdmin');
99 |
100 | Now, each time you'll invoke a method of an object of the class MyServices, starting with doAdmin, AOP will launch the function
101 | basicAdminChecker *before* the called method.
102 |
103 | That's it. Simple ain't it ?
104 |
105 | Now le's try the examples :
106 |
107 | [php]
108 | //session is started and we added the above examples to configure MyServices & basicAdminChecker
109 |
110 | $services = new MyServices();
111 | try {
112 | $services->doAdminStuff1();//will raise an exception as nothing in the current session tells us we are an admin
113 | } catch (Exception $e) {
114 | echo "You cannot access the service, you're not an admin";
115 | }
116 |
117 | $_SESSION['user_type'] = 'admin';//again, this is ugly for the sake of the example
118 |
119 | try {
120 | $service->doAdminStuff1();
121 | $service->doAdminStuff2();
122 | } catch (Exception $e) {
123 | //nothing will be caught here, we are an admin
124 | }
125 |
126 | Here you are, you know the basics of AOP.
127 |
128 | ## AOP Vocabulary and PHP's AOP capabilities ##
129 |
130 | ### Advice ###
131 |
132 | An advice is a piece of code that can be executed. In our first example the function adviceForAdmin is an advice, it
133 | *could* be executed.
134 |
135 | In PHP's AOP extension an advice can be a trait, a callback, an anonymous function, a static method of a class,
136 | a method of a given object or a closure.
137 |
138 | ### Join points ###
139 |
140 | Join points are places where we can attach advices.
141 |
142 | In PHP's AOP extension, a join point can be:
143 |
144 | * before any method / function call
145 | * after any method / function call
146 | * around any method / function call
147 | * During the arousing of an exception of any method / function
148 | * after any method / function call, should the method terminate normally or not (triggers an exception or not)
149 |
150 | In our first example, we used a "before" join point.
151 |
152 | ### Pointcut ###
153 |
154 | Pointcuts are a way to describe whether or not a given join point will trigger the execution of an advice.
155 |
156 | In PHP's AOP extension pointcuts can be configured with a quite simple and straightforward syntax.
157 |
158 | In our first example the pointcut was "MyServices->doAdmin*()" and was configured to launch the advice "before" the
159 | execution of the matching methods join points.
160 |
161 | ## Why or should I use AOP ? ##
162 |
163 | AOP is a whole different way of thinking for developing application. It is as different as object oriented programming
164 | can be opposed to procedural programming.
165 |
166 | Even if you don't want to base your future development on this approach, you may find it very useful for debugging
167 | purposes. Imagine a world where you can debug or get information on your code based only on information collected for
168 | a given user, a given context, a given procedure. A world where you can hunt weird and old code execution without even
169 | trying to update multiple and sparse PHP files, but just by adding advices on given conditions.
170 |
171 | We are sure that this extension will soon be part of your future development workflow !
172 |
--------------------------------------------------------------------------------
/doc/Contents/chapter3.md:
--------------------------------------------------------------------------------
1 | # Advanced topics #
2 |
3 | ## In which order will my pointcuts / advice will be resolved ? ##
4 |
5 | The advices are executed in the registration order.
6 |
7 | ## Is it possible to enable / disable the execution of aspects during runtime ? ##
8 |
9 | Yes it is.
10 |
11 | You can use the ini directive aop.enable to do so.
12 |
13 | [php]
14 | $cvalue) {
16 | if (strpos($cname, $constant_prefix) === 0) {
17 | $php .= 'define(\'' . $cname . '\', ' . $cvalue . ');' . N;
18 | }
19 | }
20 |
21 | $php .= N;
22 |
23 | foreach ($functions as $function) {
24 | $refl = new ReflectionFunction($function);
25 | $php .= 'function ' . $refl->getName() . '(';
26 | foreach ($refl->getParameters() as $i => $parameter) {
27 | if ($i >= 1) {
28 | $php .= ', ';
29 | }
30 | if ($typehint = $parameter->getClass()) {
31 | $php .= $typehint->getName() . ' ';
32 | }
33 | $php .= '$' . $parameter->getName();
34 | if ($parameter->isDefaultValueAvailable()) {
35 | $php .= ' = ' . $parameter->getDefaultValue();
36 | }
37 | }
38 | $php .= ') {}' . N;
39 | }
40 |
41 | $php .= N;
42 |
43 | foreach ($classes as $class) {
44 | $refl = new ReflectionClass($class);
45 | $php .= 'class ' . $refl->getName();
46 | if ($parent = $refl->getParentClass()) {
47 | $php .= ' extends ' . $parent->getName();
48 | }
49 | $php .= N . '{' . N;
50 | foreach ($refl->getProperties() as $property) {
51 | $php .= T . '$' . $property->getName() . ';' . N;
52 | }
53 | foreach ($refl->getMethods() as $method) {
54 | if ($method->isPublic()) {
55 | if ($method->getDocComment()) {
56 | $php .= T . $method->getDocComment() . N;
57 | }
58 | $php .= T . 'public function ';
59 | if ($method->returnsReference()) {
60 | $php .= '&';
61 | }
62 | $php .= $method->getName() . '(';
63 | foreach ($method->getParameters() as $i => $parameter) {
64 | if ($i >= 1) {
65 | $php .= ', ';
66 | }
67 | if ($parameter->isArray()) {
68 | $php .= 'array ';
69 | }
70 | if ($typehint = $parameter->getClass()) {
71 | $php .= $typehint->getName() . ' ';
72 | }
73 | $php .= '$' . $parameter->getName();
74 | if ($parameter->isDefaultValueAvailable()) {
75 | $php .= ' = ' . $parameter->getDefaultValue();
76 | }
77 | }
78 | $php .= ') {}' . N;
79 | }
80 | }
81 | $php .= '}';
82 | }
83 |
84 | echo $php . N;
85 |
86 |
--------------------------------------------------------------------------------
/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | AOP
4 | pecl.php.net
5 |
6 | Aspect Oriented Programming On PHP
7 |
8 |
9 | AOP is a PECL extension that enables you to use Aspect Oriented Programming in PHP, without the need to compile or proceed to any other intermediate step before publishing your code.
10 |
11 | The AOP extension is designed to be the easiest way you can think of for integrating AOP to PHP.
12 |
13 | AOP aims to allow separation of cross-cutting concerns (cache, log, security, transactions, ...)
14 |
15 |
16 | Salleyron Julien
17 | juliens
18 | juliens@php.net
19 | yes
20 |
21 |
22 | Gérald Croës
23 | gerald
24 | gerald@php.net
25 | yes
26 |
27 | 2012-11-18
28 |
29 |
30 | 0.2.2b1
31 | 0.2.0
32 |
33 |
34 | beta
35 | stable
36 |
37 | PHP License
38 | - Cache on function (With SegFault Correction)
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 | 5.3.0
218 |
219 |
220 | 1.4.8
221 |
222 |
223 |
224 | AOP
225 |
226 |
227 |
228 | 2012-07-05
229 |
230 | 0.1.0
231 | 0.1.0
232 |
233 |
234 | beta
235 | beta
236 |
237 |
238 | AOP In PHP
239 |
240 |
241 |
242 |
243 |
--------------------------------------------------------------------------------
/phpdoc/aopjoinpoint/getarguments.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | AopJoinPoint::getArguments
7 | The getArguments purpose
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public voidAopJoinPoint::getArguments
14 |
15 |
16 |
17 |
18 |
19 |
20 | &warn.undocumented.func;
21 |
22 |
23 |
24 |
25 | &reftitle.parameters;
26 | &no.function.parameters;
27 |
28 |
29 |
30 | &reftitle.returnvalues;
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
59 |
--------------------------------------------------------------------------------
/phpdoc/aopjoinpoint/getassignedvalue.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | AopJoinPoint::getAssignedValue
7 | The getAssignedValue purpose
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public voidAopJoinPoint::getAssignedValue
14 |
15 |
16 |
17 |
18 |
19 |
20 | &warn.undocumented.func;
21 |
22 |
23 |
24 |
25 | &reftitle.parameters;
26 | &no.function.parameters;
27 |
28 |
29 |
30 | &reftitle.returnvalues;
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
59 |
--------------------------------------------------------------------------------
/phpdoc/aopjoinpoint/getclassname.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | AopJoinPoint::getClassName
7 | The getClassName purpose
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public voidAopJoinPoint::getClassName
14 |
15 |
16 |
17 |
18 |
19 |
20 | &warn.undocumented.func;
21 |
22 |
23 |
24 |
25 | &reftitle.parameters;
26 | &no.function.parameters;
27 |
28 |
29 |
30 | &reftitle.returnvalues;
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
59 |
--------------------------------------------------------------------------------
/phpdoc/aopjoinpoint/getfunctionname.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | AopJoinPoint::getFunctionName
7 | The getFunctionName purpose
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public voidAopJoinPoint::getFunctionName
14 |
15 |
16 |
17 |
18 |
19 |
20 | &warn.undocumented.func;
21 |
22 |
23 |
24 |
25 | &reftitle.parameters;
26 | &no.function.parameters;
27 |
28 |
29 |
30 | &reftitle.returnvalues;
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
59 |
--------------------------------------------------------------------------------
/phpdoc/aopjoinpoint/getkindofadvice.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | AopJoinPoint::getKindOfAdvice
7 | The getKindOfAdvice purpose
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public voidAopJoinPoint::getKindOfAdvice
14 |
15 |
16 |
17 |
18 |
19 |
20 | &warn.undocumented.func;
21 |
22 |
23 |
24 |
25 | &reftitle.parameters;
26 | &no.function.parameters;
27 |
28 |
29 |
30 | &reftitle.returnvalues;
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
59 |
--------------------------------------------------------------------------------
/phpdoc/aopjoinpoint/getmethodname.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | AopJoinPoint::getMethodName
7 | The getMethodName purpose
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public voidAopJoinPoint::getMethodName
14 |
15 |
16 |
17 |
18 |
19 |
20 | &warn.undocumented.func;
21 |
22 |
23 |
24 |
25 | &reftitle.parameters;
26 | &no.function.parameters;
27 |
28 |
29 |
30 | &reftitle.returnvalues;
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
59 |
--------------------------------------------------------------------------------
/phpdoc/aopjoinpoint/getobject.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | AopJoinPoint::getObject
7 | The getObject purpose
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public voidAopJoinPoint::getObject
14 |
15 |
16 |
17 |
18 |
19 |
20 | &warn.undocumented.func;
21 |
22 |
23 |
24 |
25 | &reftitle.parameters;
26 | &no.function.parameters;
27 |
28 |
29 |
30 | &reftitle.returnvalues;
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
59 |
--------------------------------------------------------------------------------
/phpdoc/aopjoinpoint/getpointcut.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | AopJoinPoint::getPointcut
7 | The getPointcut purpose
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public voidAopJoinPoint::getPointcut
14 |
15 |
16 |
17 |
18 |
19 |
20 | &warn.undocumented.func;
21 |
22 |
23 |
24 |
25 | &reftitle.parameters;
26 | &no.function.parameters;
27 |
28 |
29 |
30 | &reftitle.returnvalues;
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
59 |
--------------------------------------------------------------------------------
/phpdoc/aopjoinpoint/getpropertyname.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | AopJoinPoint::getPropertyName
7 | The getPropertyName purpose
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public voidAopJoinPoint::getPropertyName
14 |
15 |
16 |
17 |
18 |
19 |
20 | &warn.undocumented.func;
21 |
22 |
23 |
24 |
25 | &reftitle.parameters;
26 | &no.function.parameters;
27 |
28 |
29 |
30 | &reftitle.returnvalues;
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
59 |
--------------------------------------------------------------------------------
/phpdoc/aopjoinpoint/getreturnedvalue.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | AopJoinPoint::getReturnedValue
7 | The getReturnedValue purpose
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public voidAopJoinPoint::getReturnedValue
14 |
15 |
16 |
17 |
18 |
19 |
20 | &warn.undocumented.func;
21 |
22 |
23 |
24 |
25 | &reftitle.parameters;
26 | &no.function.parameters;
27 |
28 |
29 |
30 | &reftitle.returnvalues;
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
59 |
--------------------------------------------------------------------------------
/phpdoc/aopjoinpoint/process.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | AopJoinPoint::process
7 | The process purpose
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public voidAopJoinPoint::process
14 |
15 |
16 |
17 |
18 |
19 |
20 | &warn.undocumented.func;
21 |
22 |
23 |
24 |
25 | &reftitle.parameters;
26 | &no.function.parameters;
27 |
28 |
29 |
30 | &reftitle.returnvalues;
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
59 |
--------------------------------------------------------------------------------
/phpdoc/aopjoinpoint/setarguments.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | AopJoinPoint::setArguments
7 | The setArguments purpose
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public voidAopJoinPoint::setArguments
14 |
15 |
16 |
17 |
18 |
19 |
20 | &warn.undocumented.func;
21 |
22 |
23 |
24 |
25 | &reftitle.parameters;
26 | &no.function.parameters;
27 |
28 |
29 |
30 | &reftitle.returnvalues;
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
59 |
--------------------------------------------------------------------------------
/phpdoc/aopjoinpoint/setassignedvalue.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | AopJoinPoint::setAssignedValue
7 | The setAssignedValue purpose
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public voidAopJoinPoint::setAssignedValue
14 |
15 |
16 |
17 |
18 |
19 |
20 | &warn.undocumented.func;
21 |
22 |
23 |
24 |
25 | &reftitle.parameters;
26 | &no.function.parameters;
27 |
28 |
29 |
30 | &reftitle.returnvalues;
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
59 |
--------------------------------------------------------------------------------
/phpdoc/aopjoinpoint/setreturnedvalue.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | AopJoinPoint::setReturnedValue
7 | The setReturnedValue purpose
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | public voidAopJoinPoint::setReturnedValue
14 |
15 |
16 |
17 |
18 |
19 |
20 | &warn.undocumented.func;
21 |
22 |
23 |
24 |
25 | &reftitle.parameters;
26 | &no.function.parameters;
27 |
28 |
29 |
30 | &reftitle.returnvalues;
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
59 |
--------------------------------------------------------------------------------
/phpdoc/aoptriggeredjoinpoint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | The AopJoinPoint class
7 | AopJoinPoint
8 |
9 |
10 |
11 |
12 |
13 | &reftitle.intro;
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | &reftitle.classsynopsis;
22 |
23 |
24 |
25 | AopJoinPoint
26 |
27 |
28 |
29 |
30 | AopJoinPoint
31 |
32 |
33 |
34 |
35 | &Methods;
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | &reference.aop.entities.AopJoinPoint;
45 |
46 |
47 |
48 |
68 |
--------------------------------------------------------------------------------
/phpdoc/book.developer.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 | %xhtml-lat1;
12 | %xhtml-symbol;
13 | %xhtml-special;
14 | %isopub;
15 |
16 |
17 |
18 |
19 |
20 |
21 | %language-defs.default;
22 | %extensions.default;
23 | %language-snippets.default;
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | %global.entities;
34 | %file.entities;
35 | %frontpage.entities;
36 | ]>
37 |
38 |
39 | Aop
40 | Aop
41 |
42 |
43 | &reftitle.intro;
44 |
45 |
46 |
47 |
48 |
49 | &reference.aop.setup;
50 | &reference.aop.constants;
51 | &reference.aop.examples;
52 | &reference.aop.reference;
53 |
54 |
55 |
56 |
76 |
77 |
--------------------------------------------------------------------------------
/phpdoc/book.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Aspect Oriented Programming On Php
6 | AOP
7 |
8 |
9 | &reftitle.intro;
10 |
11 |
12 | The Aspect Oriented Programming On PHP is a free and open aspect weaver for PHP.
13 | Its goal is to provide an easy way to integrate Aspect Oriented Programming techniques into PHP.
14 |
15 |
16 |
17 | Aspect Oriented Programming Goals
18 |
19 | Aspect Oriented Programming complements Object Oriented Programming as well as Imperative programming by adding aspects
20 | that enables modularization of cross cutting concerns (caching, transaction management, logging, security, ...).
21 | Without AOP, programming often lead into decomposing the software into units of primary functionnality, while knowing
22 | that other concerns cut across thoose units. Programmers are then led to code the behaviour of thoose concerns
23 | wherever needed in the primary functionnal units.
24 | AOP enable programmers to modularize thoose concerns, while giving tools to automaticaly spread thoose behaviour
25 | were expected.
26 |
27 |
28 |
29 | AOP Terminology
30 |
31 |
32 |
33 |
34 | Join point
35 |
36 |
37 |
38 | A join point is a point in the program execution worklflow where programmers will get the opportunity to add
39 | a given behaviour. In AOP, a join point can be a function call, a method call or a property operation (read or
40 | write). The join point informations (AopJoinPoint) will be given to advices as a first parameter.
41 |
42 |
43 |
44 |
45 |
46 | Advice
47 |
48 |
49 |
50 | Action taken at a given join point. In AOP, advices are callbacks. Advices can be of different types : "after",
51 | "around", "before", and more specifically "afterreturning" or "afterthrowing".
52 |
53 |
54 |
55 |
56 |
57 | Pointcut
58 |
59 |
60 |
61 | A pointcut is a set of join points. In AOP, pointcuts are predicates. Like SQL statements results
62 | in a particular set of rows, a pointcut results in a particular set of join points.
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | &reference.aop.setup;
72 | &reference.aop.constants;
73 | &reference.aop.pointcut;
74 | &reference.aop.reference;
75 |
76 |
77 |
78 |
98 |
--------------------------------------------------------------------------------
/phpdoc/configure.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | &reftitle.install;
6 |
7 |
8 | &pecl.info;
9 | &url.pecl.package;aop
10 |
11 |
12 |
13 |
14 |
15 |
16 |
36 |
--------------------------------------------------------------------------------
/phpdoc/constants.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | &reftitle.constants;
6 | &extension.constants;
7 |
8 |
9 |
10 |
11 | AOP_KIND_BEFORE
12 | (integer)
13 |
14 |
15 |
16 | Represents a joinpoint triggered before any function or method call, or before any read or write property operation.
17 |
18 |
19 |
20 |
21 |
22 | AOP_KIND_AFTER
23 | (integer)
24 |
25 |
26 |
27 | Represents a joinpoint triggered after any function or method call, or after any read or write property operation.
28 |
29 |
30 |
31 |
32 |
33 | AOP_KIND_AROUND
34 | (integer)
35 |
36 |
37 |
38 | Represents a joinpoint triggered around any function or method call, or after any read or write property operation.
39 |
40 |
41 |
42 |
43 |
44 | AOP_KIND_PROPERTY
45 | (integer)
46 |
47 |
48 |
49 | Represents a joinpoint triggered in any read or write property operation, may it be before, around of after the operation.
50 |
51 |
52 |
53 |
54 |
55 | AOP_KIND_FUNCTION
56 | (integer)
57 |
58 |
59 |
60 | Represents a joinpoint triggered before, around of after a function call (not method call).
61 |
62 |
63 |
64 |
65 |
66 | AOP_KIND_METHOD
67 | (integer)
68 |
69 |
70 |
71 | Represents a joinpoint triggered before, around of after a method call (not function call).
72 |
73 |
74 |
75 |
76 |
77 | AOP_KIND_READ
78 | (integer)
79 |
80 |
81 |
82 | Represents a joinpoint triggered before, around of after a property read operation.
83 |
84 |
85 |
86 |
87 |
88 | AOP_KIND_WRITE
89 | (integer)
90 |
91 |
92 |
93 | Represents a joinpoint triggered before, around of after a property write operation.
94 |
95 |
96 |
97 |
98 |
99 | AOP_KIND_AROUND_WRITE_PROPERTY
100 | (integer)
101 |
102 |
103 |
104 | Represents a joinpoint triggered around a property write operation.
105 |
106 |
107 |
108 |
109 |
110 | AOP_KIND_AROUND_READ_PROPERTY
111 | (integer)
112 |
113 |
114 |
115 | Represents a joinpoint triggered around a property read operation.
116 |
117 |
118 |
119 |
120 |
121 | AOP_KIND_BEFORE_WRITE_PROPERTY
122 | (integer)
123 |
124 |
125 |
126 | Represents a joinpoint triggered before a property write operation.
127 |
128 |
129 |
130 |
131 |
132 | AOP_KIND_BEFORE_READ_PROPERTY
133 | (integer)
134 |
135 |
136 |
137 | Represents a joinpoint triggered around a property read operation.
138 |
139 |
140 |
141 |
142 |
143 | AOP_KIND_AFTER_WRITE_PROPERTY
144 | (integer)
145 |
146 |
147 |
148 | Represents a joinpoint triggered after a property write operation.
149 |
150 |
151 |
152 |
153 |
154 | AOP_KIND_AFTER_READ_PROPERTY
155 | (integer)
156 |
157 |
158 |
159 | Represents a joinpoint triggered after a property read operation.
160 |
161 |
162 |
163 |
164 |
165 | AOP_KIND_BEFORE_METHOD
166 | (integer)
167 |
168 |
169 |
170 | Represents a joinpoint triggered before a method call.
171 |
172 |
173 |
174 |
175 |
176 | AOP_KIND_AFTER_METHOD
177 | (integer)
178 |
179 |
180 |
181 | Represents a joinpoint triggered after a method call.
182 |
183 |
184 |
185 |
186 |
187 | AOP_KIND_AROUND_METHOD
188 | (integer)
189 |
190 |
191 |
192 | Represents a joinpoint triggered around a method call.
193 |
194 |
195 |
196 |
197 |
198 | AOP_KIND_BEFORE_FUNCTION
199 | (integer)
200 |
201 |
202 |
203 | Represents a joinpoint triggered before a function call.
204 |
205 |
206 |
207 |
208 |
209 | AOP_KIND_AFTER_FUNCTION
210 | (integer)
211 |
212 |
213 |
214 | Represents a joinpoint triggered after a function call.
215 |
216 |
217 |
218 |
219 |
220 | AOP_KIND_AROUND_FUNCTION
221 | (integer)
222 |
223 |
224 |
225 | Represents a joinpoint triggered around a function call.
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
253 |
--------------------------------------------------------------------------------
/phpdoc/entities.aopjoinpoint.xml:
--------------------------------------------------------------------------------
1 | &reference.aop.aopjoinpoint.getarguments;
2 | &reference.aop.aopjoinpoint.getassignedvalue;
3 | &reference.aop.aopjoinpoint.getclassname;
4 | &reference.aop.aopjoinpoint.getfunctionname;
5 | &reference.aop.aopjoinpoint.getkindofadvice;
6 | &reference.aop.aopjoinpoint.getmethodname;
7 | &reference.aop.aopjoinpoint.getobject;
8 | &reference.aop.aopjoinpoint.getpointcut;
9 | &reference.aop.aopjoinpoint.getpropertyname;
10 | &reference.aop.aopjoinpoint.getreturnedvalue;
11 | &reference.aop.aopjoinpoint.process;
12 | &reference.aop.aopjoinpoint.setarguments;
13 | &reference.aop.aopjoinpoint.setassignedvalue;
14 | &reference.aop.aopjoinpoint.setreturnedvalue;
15 |
--------------------------------------------------------------------------------
/phpdoc/entities.functions.xml:
--------------------------------------------------------------------------------
1 | &reference.aop.functions.aop-add-after;
2 | &reference.aop.functions.aop-add-around;
3 | &reference.aop.functions.aop-add-before;
4 |
--------------------------------------------------------------------------------
/phpdoc/functions/aop-add-after.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | aop_add_after
7 | Adds an advice to be run after the matching join points
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | voidaop_add_after
14 | stringpointcut
15 | callableadvice
16 |
17 |
18 | Associate an advice to a pointcut. The advice will be run right after the join points, may it end normally or not.
19 |
20 |
21 |
22 |
23 | &reftitle.parameters;
24 |
25 |
26 | pointcut
27 |
28 |
29 | A predicate that matches join points. Advices are associated with a pointcut expression and runs at any join point
30 | matched by the pointcut (for example, the execution of a method with a certain name).
31 |
32 |
33 |
34 |
35 | advice
36 |
37 |
38 | The action taken by the aspect. When a join point that match the pointcut will be encountered, the advice will be run.
39 | The callback will get a JoinPoint object as its first parameter.
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | &reftitle.returnvalues;
48 |
49 |
50 |
51 |
52 |
53 |
54 | &reftitle.examples;
55 |
56 |
57 | A simple aop_add_after example
58 |
59 | getReturnedValue(), "\n";
63 | };
64 |
65 | class Calculator
66 | {
67 | public function __construct($initialValue = 0)
68 | {
69 | $this->total = $initialValue;
70 | }
71 |
72 | public function add($number)
73 | {
74 | return $this->total += $number;
75 | }
76 | }
77 |
78 | aop_add_after('Calculator->add()', $advice);
79 |
80 | $calculator = new Calculator();
81 | $calculator->add(4);
82 | $calculator->add(2);
83 | $calculator->add(1);
84 | ?>
85 | ]]>
86 |
87 | &example.outputs;
88 |
89 |
94 |
95 |
96 |
97 |
98 |
99 |
100 | &reftitle.seealso;
101 |
102 |
103 | aop_add_around
104 | aop_add_before
105 |
106 |
107 |
108 |
109 |
110 |
111 |
131 |
--------------------------------------------------------------------------------
/phpdoc/functions/aop-add-around.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | aop_add_around
7 | Adds an advice to be run around the matching join points
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | ReturnTypeaop_add_around
14 | stringpointcut
15 | callableadvice
16 |
17 |
18 | Associate an advice to a pointcut. The advice will surrounds the join points. The advice will get the opportunity
19 | to perform custom behavior before and after the method invocation or property operation. It is also responsible for
20 | choosing whether to proceed to the join point or to shortcut the advised element by returning its own return
21 | value or throwing an exception.
22 |
23 |
24 | &warn.undocumented.func;
25 |
26 |
27 |
28 |
29 | &reftitle.parameters;
30 |
31 |
32 | pointcut
33 |
34 |
35 | A predicate that matches join points. Advices are associated with a pointcut expression and runs at any join point
36 | matched by the pointcut (for example, the execution of a method with a certain name).
37 |
38 |
39 |
40 |
41 | advice
42 |
43 |
44 | The action taken by the aspect. When a join point that match the pointcut will be encountered, the advice will be run.
45 | The callback will get a JoinPoint object as its first parameter.
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | &reftitle.returnvalues;
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
82 |
--------------------------------------------------------------------------------
/phpdoc/functions/aop-add-before.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | aop_add_before
7 | Adds an advice to be run before the matching join points
8 |
9 |
10 |
11 | &reftitle.description;
12 |
13 | ReturnTypeaop_add_before
14 | stringpointcut
15 | callableadvice
16 |
17 |
18 | Associate an advice to a pointcut. The advice will be run right before the join points.
19 |
20 |
21 |
22 |
23 |
24 | &reftitle.parameters;
25 |
26 |
27 | pointcut
28 |
29 |
30 | A predicate that matches join points. Advices are associated with a pointcut expression and runs at any join point
31 | matched by the pointcut (for example, the execution of a method with a certain name).
32 |
33 |
34 |
35 |
36 | advice
37 |
38 |
39 | The action taken by the aspect. When a join point that match the pointcut will be encountered, the advice will be run.
40 | The callback will get a JoinPoint object as its first parameter.
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | &reftitle.returnvalues;
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
77 |
--------------------------------------------------------------------------------
/phpdoc/pointcut.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Pointcut syntax
6 |
7 | Poincuts are predicates that matches join points. Advices are associated with a pointcut expression and runs at any join point
8 | matched by the pointcut.
9 |
10 |
11 | Pointcuts can describe functions, method calls (public, protected, private, static or not) and properties operations
12 | (read, write, public, protected or private).
13 |
14 |
15 | Pointcuts can contain namespaces if needed.
16 |
17 |
18 | The special character * (wildcard) can be use to match any number of any character for a given element (namespace element,
19 | function name, method name, class name or property name).
20 |
21 |
22 | Two wildcards ** will match any number of any character for the namespace path.
23 |
24 |
25 | When describing a function call or a method call, pointcuts must end with parenthesis (). When describing a property
26 | operation, pointcuts should contain only the class and property name, with no parenthesis.
27 |
28 |
29 |
30 | As PHP itself, pointcuts are case sensitive while describing properties but are case insensitive while describing
31 | functions, methods, classes, interfaces or traits.
32 |
33 |
34 |
35 | Function calls
36 |
37 | The following example shows several syntax for describing a function call.
38 |
39 |
40 | foo()
43 | $pointcut = 'foo()';
44 |
45 | //will match foo(), fooo(), fooBar() and so on, but not foo\bar() or bar\foo()
46 | $pointcut = 'foo*()';
47 |
48 | //will match foobar(), foooBar(), someBar() and so on, but not foo\bar() or bar\fooBar()
49 | $pointcut = '*bar()';
50 |
51 | //will match foo\bar(), but NOT foo\foo\bar();
52 | $pointcut = 'foo\\bar()';
53 |
54 | //will match foo\bar(), foo\bigbar(), foo\barfoobar() but NOT foo\bar\bar()
55 | $pointcut = 'foo\\b*()';
56 |
57 | //will match foobar\anything(), foobarAnything\anything() but NOT foobar\foo\bar();
58 | $pointcut = 'foobar*\\*()';
59 |
60 | //will match some\foo\bar(), some\other\bar() but NOT foo\bar() of some\longer\foo\bar()
61 | $pointcut = '*\\*\\bar()';
62 |
63 | //will match any\namespace\where\is\foo() including foo()
64 | $pointcut = '**\\foo()';
65 |
66 | //will match startWithFooSomething\anything\anything_else\bar() including startWithFoo\bar();
67 | $pointcut = 'StartWithFoo*\\**\\bar()'; //same as 'StartWithFoo**\\bar()';
68 | ?>
69 | ]]>
70 |
71 |
72 |
73 |
74 |
75 | Method calls
76 |
77 | The following example shows several syntax for describing a method call.
78 |
79 |
80 | bar(), foo->Bar() and foo->bar(), where Foo is the type (class, interface or trait) of the object and bar the name of the called method.
83 | //Won't match namespaceFoo\Foo->Bar()
84 | $pointcut = 'Foo->bar()';
85 |
86 | //will match Foo->bar(), fooBar->bar(), anything->bar() but NOT namespaceFoo\foo->Bar();
87 | $pointcut = '*->bar()';
88 |
89 | //will match foo->bar(), foo->fooBar(), fooBarFoo->foofooBar() but NOT namespace1\foo->bar()
90 | $pointcut = '*foo->*bar()';
91 |
92 | //will match foo\bar->bar(), foo\foo->bar() but NOT foo\bar\foo->bar();
93 | $pointcut = 'foo\\*->bar()';
94 |
95 | //will match foobar\foobar\anything->bar(), but NOT foobar\foo->bar()
96 | $pointcut = '*bar\\foo*\\*->bar()';
97 |
98 | //will match any method of objects of any types in any namespaces
99 | $pointcut = '**\\*->*()';
100 | ?>
101 | ]]>
102 |
103 |
104 |
105 |
106 |
107 | Property operation
108 |
109 | The following example shows several syntax for describing a property operation.
110 |
111 |
112 | bar, foo->bar = 'foo' and Foo->bar++, where Foo is the type (class, interface or trait) of the object and bar the name of the accessed property
115 | //Won't match namespaceFoo\Foo->bar or Foo->Bar (case sensitive)
116 | $pointcut = 'Foo->bar';
117 |
118 | //will match echo Foo->bar, fooBar->bar, anything->bar but NOT namespaceFoo\foo->bar (namespace does not match);
119 | $pointcut = '*->bar';
120 |
121 | //will match foo->bar, foo->Foobar, fooBarFoo->fooFoobar but NOT namespace1\foo->bar (namespace does not match)
122 | $pointcut = '*foo->*bar';
123 |
124 | //will match foo\bar->bar, foo\foo->bar but NOT foo\bar\foo->bar (the object should be directly in the foo namespace);
125 | $pointcut = 'foo\\*->bar';
126 |
127 | //will match foobar\foobar\anything->bar, but NOT foobar\foo->bar (the object should be in a two level namespace described as in the pointcut)
128 | $pointcut = '*bar\\foo*\\*->bar';
129 |
130 | //will match any property operation of objects of any types in any namespaces
131 | $pointcut = '**\\*->*';
132 | ?>
133 | ]]>
134 |
135 |
136 |
137 |
138 |
139 | Using visibility operators
140 |
141 | The following example shows several syntax for describing operations that takes visibility into account
142 |
143 |
144 | bar()', but not by 'protected Foo->bar()'
149 | public function bar () {
150 | }
151 |
152 | //will be matched by '!public Foo->foo()', 'protected | private Foo->foo()'
153 | protected function foo () {
154 | }
155 | }
156 | ?>
157 | ]]>
158 |
159 |
160 |
161 |
162 |
163 |
164 |
184 |
--------------------------------------------------------------------------------
/phpdoc/reference.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Aop &Functions;
6 |
7 | &reference.aop.entities.functions;
8 |
9 |
10 |
11 |
31 |
--------------------------------------------------------------------------------
/phpdoc/setup.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | &reftitle.setup;
6 |
7 |
8 | &reftitle.required;
9 | &no.requirement;
10 |
11 |
12 |
13 | &reftitle.install;
14 |
15 | &pecl.moved;
16 |
17 |
18 | &pecl.info;
19 | &url.pecl.package;aop.
20 |
21 |
22 | &pecl.windows.download;
23 |
24 |
25 |
26 |
27 |
28 |
48 |
--------------------------------------------------------------------------------
/phpdoc/versions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
49 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 | ./tests/
9 |
10 |
11 |
--------------------------------------------------------------------------------
/tests/after_returning/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | aop_add_after_returning triggers only when functions / methods ends properly
3 | --FILE--
4 | doStuff";
16 | }
17 |
18 | public function doStuffException () {
19 | echo "Stuff->doStuffException";
20 | throw new Exception('Exception doStuffException');
21 | }
22 |
23 | public static function doStuffStatic () {
24 | echo "Stuff::doStuffStatic";
25 | }
26 |
27 | public static function doStuffStaticException () {
28 | echo "Stuff::doStuffStaticException";
29 | throw new Exception('Exception doStuffStaticException');
30 | }
31 | }
32 |
33 | aop_add_after_returning('doStuff*()', function() {
34 | echo "[after]";
35 | });
36 | aop_add_after_returning('Stuff->doStuff*()', function() {
37 | echo "[after]";
38 | });
39 |
40 | doStuff();
41 | try {
42 | doStuffException();
43 | } catch (Exception $e) {
44 | echo "[caught]";
45 | }
46 | $stuff = new Stuff();
47 |
48 | $stuff->doStuff();
49 | try {
50 | $stuff->doStuffException();
51 | } catch (Exception $e) {
52 | echo "[caught]";
53 | }
54 | Stuff::doStuffStatic();
55 | try {
56 | Stuff::doStuffStaticException();
57 | } catch (Exception $e) {
58 | echo "[caught]";
59 | }
60 | --EXPECT--
61 | doStuff[after]doStuffException[caught]Stuff->doStuff[after]Stuff->doStuffException[caught]Stuff::doStuffStatic[after]Stuff::doStuffStaticException[caught]
62 |
--------------------------------------------------------------------------------
/tests/after_throwing/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | aop_add_after_returning triggers only when functions / methods ends properly
3 | --FILE--
4 | doStuff";
16 | }
17 |
18 | public function doStuffException () {
19 | echo "Stuff->doStuffException";
20 | throw new Exception('Exception doStuffException');
21 | }
22 |
23 | public static function doStuffStatic () {
24 | echo "Stuff::doStuffStatic";
25 | }
26 |
27 | public static function doStuffStaticException () {
28 | echo "Stuff::doStuffStaticException";
29 | throw new Exception('Exception doStuffStaticException');
30 | }
31 | }
32 |
33 | aop_add_after_throwing('doStuff*()', function() {
34 | echo "[after]";
35 | });
36 | aop_add_after_throwing('Stuff->doStuff*()', function() {
37 | echo "[after]";
38 | });
39 |
40 | doStuff();
41 | try {
42 | doStuffException();
43 | } catch (Exception $e) {
44 | echo "[caught]";
45 | }
46 | $stuff = new Stuff();
47 |
48 | $stuff->doStuff();
49 | try {
50 | $stuff->doStuffException();
51 | } catch (Exception $e) {
52 | echo "[caught]";
53 | }
54 | Stuff::doStuffStatic();
55 | try {
56 | Stuff::doStuffStaticException();
57 | } catch (Exception $e) {
58 | echo "[caught]";
59 | }
60 | --EXPECT--
61 | doStuffdoStuffException[after][caught]Stuff->doStuffStuff->doStuffException[after][caught]Stuff::doStuffStaticStuff::doStuffStaticException[after][caught]
62 |
--------------------------------------------------------------------------------
/tests/arguments_overload/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Args overload arguments call (try in the first around declared)
3 | --FILE--
4 | getArguments());$pObj->process();});
13 | aop_add_around("mytest::test()",function ($pObj) {
14 | echo "OVERLOAD\n";
15 | var_dump($pObj->getArguments());
16 | $pObj->setArguments(array ('overload'));
17 | $pObj->process();
18 | });
19 |
20 |
21 | $test = new mytest();
22 | $test->test("first");
23 |
24 | ?>
25 | --EXPECT--
26 | NOOVERLOAD
27 | array(1) {
28 | [0]=>
29 | string(5) "first"
30 | }
31 | OVERLOAD
32 | array(1) {
33 | [0]=>
34 | string(5) "first"
35 | }
36 | string(8) "overload"
37 |
38 |
--------------------------------------------------------------------------------
/tests/arguments_overload/002.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | args overload arguments call (try in the second around declared)
3 | --FILE--
4 | getArguments());
15 | $pObj->setArguments(array('overload'));
16 | $pObj->process();
17 | });
18 |
19 | aop_add_around("mytest::test()",function ($pObj) {echo "NOOVERLOAD\n";var_dump($pObj->getArguments());$pObj->process();});
20 | $test = new mytest();
21 | $test->test("first");
22 |
23 | ?>
24 | --EXPECT--
25 | OVERLOAD
26 | array(1) {
27 | [0]=>
28 | string(5) "first"
29 | }
30 | NOOVERLOAD
31 | array(1) {
32 | [0]=>
33 | string(8) "overload"
34 | }
35 | string(8) "overload"
36 |
37 |
--------------------------------------------------------------------------------
/tests/articles/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Fluent interface fun with aop
3 | --SKIPIF--
4 | skip "Bad test, to be corrected"
5 | --FILE--
6 | stuff = $value;
13 | }
14 | public function getStuff() {
15 | return $this->stuff;
16 | }
17 | }
18 |
19 | class BeFluent implements Fluent {
20 | private $stuff;
21 |
22 | public function setStuff($value) {
23 | $this->stuff = $value;
24 | }
25 | public function getStuff() {
26 | return $this->stuff;
27 | }
28 | }
29 |
30 | class NotFluent {
31 | private $stuff;
32 | public function setStuff($value) {
33 | $this->stuff = $value;
34 | }
35 | public function getStuff() {
36 | return $this->stuff;
37 | }
38 | }
39 |
40 | aop_add_after_returning("Fluent->set*()", function (AopJoinPoint $jp) {
41 | if ($jp->getReturnedValue() === null) {
42 | // echo "I'm updating {$jp->getMethodName()} in {$jp->getClassName()}, now returning this";
43 | $jp->setReturnedValue($jp->getObject());
44 | }
45 | });
46 |
47 | $beFluent = new BeFluent();
48 | $result = $beFluent->setStuff('stuff')->setStuff('stuff2');
49 | echo $result === $beFluent ? "ok" : "ko";
50 |
51 | /*
52 | try {
53 | $willBeFluent->setStuff('stuff')->setStuff('stuff2')->setStuff('stuff3');
54 | } catch (Exception $e) {
55 | echo "Stopped being fluent...";
56 | }
57 | */
58 |
59 | $notFluent = new NotFluent();
60 | $result = $notFluent->setStuff('stuff');
61 |
62 | echo $result === $notFluent ? "ko" : "ok";
63 | ?>
64 | --EXPECT--
65 | okStopped being fluent...ok
66 |
--------------------------------------------------------------------------------
/tests/autoload/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | No autoload for selector
3 | --FILE--
4 | test();
16 | echo "OK";
17 | ?>
18 | --EXPECT--
19 | OK
20 |
--------------------------------------------------------------------------------
/tests/bugs/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Two call to getTriggeringMethodName doesn't segfault
3 | --FILE--
4 | data;
10 | }
11 | }
12 |
13 | aop_add_around("A::test()", function ($pObj) {
14 | echo $pObj->getMethodName().'|'.$pObj->getMethodName();
15 | });
16 | $test = new A();
17 | $test->test();
18 |
19 | ?>
20 | --EXPECT--
21 | test|test
22 |
--------------------------------------------------------------------------------
/tests/bugs/002.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Call tostring is property is object
3 | --FILE--
4 | test");
10 | $test = new A();
11 | echo $test->$name;
12 | aop_add_before("A::test", function ($pObj) {
13 | echo "catch";
14 | });
15 | echo $test->$name;
16 | $test->$name = "toto";
17 | ?>
18 | --EXPECT--
19 | datacatchdatacatch
20 |
--------------------------------------------------------------------------------
/tests/bugs/003.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | aop on private property
3 | --FILE--
4 | _data = $pData;
12 | }
13 | public function write () {
14 | echo $this->_data;
15 | }
16 | }
17 |
18 | aop_add_around ('A::*', function ($pObj) {
19 | echo "catch";
20 | $pObj->process();
21 | });
22 |
23 | $a = new A ();
24 |
25 | $a->set ('test');
26 | $a->write();
27 |
28 | ?>
29 | --EXPECT--
30 | catchcatchtest
31 |
--------------------------------------------------------------------------------
/tests/bugs/004.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | aop on private property
3 | --FILE--
4 | toto = 'titi';
13 | self::$_data = $pData;
14 | }
15 | public static function write () {
16 | echo self::$_data;
17 | }
18 | }
19 |
20 | aop_add_around ('private An::tte', function ($pObj) {
21 | echo "catch";
22 | $pObj->process();
23 | });
24 |
25 |
26 | A::set('test');
27 | A::write();
28 | ?>
29 | --EXPECT--
30 | test
31 |
--------------------------------------------------------------------------------
/tests/bugs/005.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Try using finfo_open
3 | --SKIPIF--
4 |
9 | --FILE--
10 |
14 | --EXPECT--
15 | text/plain
16 |
--------------------------------------------------------------------------------
/tests/bugs/006.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Try using new finfo()
3 | --SKIPIF--
4 |
9 | --FILE--
10 | test()->file(__FILE__);
19 | ?>
20 | --EXPECTF--
21 | text/x-%s
22 |
--------------------------------------------------------------------------------
/tests/bugs/007.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Try using finfo_open (may cause segmentation fault)
3 | --SKIPIF--
4 |
9 | --FILE--
10 | test();
19 | echo 'PASS';
20 | ?>
21 | --EXPECT--
22 | PASS
23 |
--------------------------------------------------------------------------------
/tests/cache/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test if cache is refresh
3 | --FILE--
4 | var1 = "test";
13 |
14 | aop_add_before("mytest::var1", function ($pObj) { echo "second\n"; });
15 | $test->var1 = "test";
16 | ?>
17 | --EXPECT--
18 | first
19 | first
20 | second
21 |
--------------------------------------------------------------------------------
/tests/cache/002.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test if handle number is enought and realloc if problem
3 | --FILE--
4 | var1 = "test";
17 |
18 | ?>
19 | --EXPECT--
20 | first
21 |
--------------------------------------------------------------------------------
/tests/cache/003.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test if handle number is enought and realloc if problem
3 | --FILE--
4 | var1 = "test";
17 | unset ($test);
18 | $test = new truc();
19 | $test->var1 = "test";
20 |
21 | ?>
22 | --EXPECT--
23 | first
24 |
--------------------------------------------------------------------------------
/tests/complete/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Caching example with multiple objects with advices on
3 | --FILE--
4 | getArguments();
28 | $idData = $callArguments[0];
29 |
30 | //On récupère le nom de la méthode appelée (doGetDataQqchose)
31 | $calledMethodName = $jp->getMethodName();
32 |
33 | //vérifie s'il existe un cache pour l'appel courant
34 | if (isset($cache[$calledMethodName][$idData])) {
35 | return $cache[$calledMethodName][$idData];
36 | } else {
37 | //Le cache n'existe pas, on exécute la méthode d'origine
38 | $cache[$calledMethodName][$idData] = $jp->process(); }
39 | };
40 |
41 | aop_add_around('Services->doGetDataOn*()', $conseil);
42 |
43 | $service1 = new Services();
44 | echo $service1->doGetDataOn(1);
45 | $service2 = new Services();
46 | echo $service2->doGetDataOn2(1);
47 | //Now the cache is loaded for bot doGetDataOn(1) and doGetDataOn2(1)
48 | echo $service1->doGetDataOn2(1);
49 | echo $service2->doGetDataOn(1);
50 | //Making another call on doGetDataOn(2)
51 | echo $service2->doGetDataOn(2);
52 | echo $service1->doGetDataOn(2);
53 | ?>
54 | --EXPECT--
55 | Calculating doGetDataOn(1)
56 | doGetDataOn(1)
57 | Calculating doGetDataOn2(1)
58 | doGetDataOn2(1)
59 | doGetDataOn2(1)
60 | doGetDataOn(1)
61 | Calculating doGetDataOn(2)
62 | doGetDataOn(2)
63 | doGetDataOn(2)
64 |
--------------------------------------------------------------------------------
/tests/consts/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Testing AOP_KIND_AROUND constant
3 | --FILE--
4 | getKindOfAdvice() === AOP_KIND_AROUND_METHOD ? 'yes' : 'no'; });
11 | $test = new mytest();
12 | $test->test();
13 |
14 | ?>
15 | --EXPECT--
16 | yes
17 |
--------------------------------------------------------------------------------
/tests/consts/002.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Testing AOP_KIND_BEFORE constant
3 | --FILE--
4 | getKindOfAdvice() === AOP_KIND_BEFORE_METHOD ? 'yes' : 'no'; });
11 | $test = new mytest();
12 | $test->test();
13 |
14 | ?>
15 | --EXPECT--
16 | yesintest
17 |
--------------------------------------------------------------------------------
/tests/consts/003.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Testing AOP_KIND_AFTER constant
3 | --FILE--
4 | getKindOfAdvice() | AOP_KIND_AFTER_METHOD ? 'yes' : 'no'; });
11 | $test = new mytest();
12 | $test->test();
13 |
14 | ?>
15 | --EXPECT--
16 | intestyes
17 |
--------------------------------------------------------------------------------
/tests/consts/004.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Testing that AOP_* consts are different
3 | --FILE--
4 |
10 | --EXPECT--
11 | yyy
12 |
--------------------------------------------------------------------------------
/tests/context/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Verify this context in method caught (private version)
3 | --FILE--
4 | data;
10 | }
11 | }
12 |
13 | aop_add_around("A::test()", function ($pObj) { return "[".$pObj->process()."]";});
14 | $test = new A();
15 | echo $test->test();
16 |
17 | ?>
18 | --EXPECT--
19 | [testvalue]
20 |
--------------------------------------------------------------------------------
/tests/context/002.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Verify this context in method caught (public version)
3 | --FILE--
4 | data;
10 | }
11 | }
12 |
13 | aop_add_around("mytest::test()", function ($pObj) {return "around".$pObj->process();});
14 | $test = new mytest();
15 | $test->data="prop";
16 | echo $test->test();
17 |
18 | ?>
19 | --EXPECT--
20 | aroundtest-prop
21 |
--------------------------------------------------------------------------------
/tests/docsexample/0.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Docs Test 0
3 | --FILE--
4 | doStuff();
21 |
22 | ?>
23 | --EXPECT--
24 | I was called before doing stuff...do my best stuff !
25 |
26 |
--------------------------------------------------------------------------------
/tests/docsexample/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Docs Example 1
3 | --FILE--
4 | doStuff();
22 | ?>
23 | --EXPECT--
24 | I was called before doing stuff...do my best stuff !
25 |
--------------------------------------------------------------------------------
/tests/docsexample/002.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Docs Example 2
3 | --FILE--
4 | doStuff();
26 | } catch (Exception $e) {
27 | echo $e->getMessage();
28 | }
29 | ?>
30 | --EXPECT--
31 | I will never do that with someone I don't know
32 |
--------------------------------------------------------------------------------
/tests/docsexample/003.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Internal Return
3 | --FILE--
4 | getReturnedValue());
7 | });
8 | $return = str_replace('test','test','test');
9 | str_replace('test1','test1','test1');
10 | ?>
11 | --EXPECT--
12 | string(4) "test"
13 | string(5) "test1"
14 |
15 |
--------------------------------------------------------------------------------
/tests/docsexample/1.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Docs Test 1
3 | --FILE--
4 | doStuff();
25 | } catch (Exception $e) {
26 | echo $e->getMessage();
27 | }
28 |
29 | ?>
30 | --EXPECT--
31 | I will never do that with someone I don't know
32 |
33 |
--------------------------------------------------------------------------------
/tests/docsexample/10.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Docs Test 10
3 | --FILE--
4 | process();
15 | $returnValue = $joinpoint->getReturnedValue();
16 | $returnValue = str_replace('best', 'very best', $returnValue);
17 | $joinpoint->setReturnedValue($returnValue);
18 | };
19 |
20 | aop_add_around('MyServices::doStuff()', $advice);
21 |
22 | $services = new MyServices();
23 | echo $services->doStuff();
24 |
25 | ?>
26 | --EXPECT--
27 | doing my very best stuff !
28 |
29 |
--------------------------------------------------------------------------------
/tests/docsexample/11.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Docs Test 11
3 | --FILE--
4 | getArguments();
11 | $args[0] = 'NEW Name';//won't update the original $name parameter as it is a value
12 | $args[1] = 'UPDATED $reference';//WILL update the original $reference parameter as it is a reference
13 | };
14 |
15 | aop_add_before('callMe()', $advice);
16 |
17 | $name = "name";
18 | $reference = "reference";
19 | callMe($name, $reference);
20 | echo "After the method execution, value of name is $name and value of reference is $reference";
21 |
22 | ?>
23 | --EXPECT--
24 | name and UPDATED $reference. After the method execution, value of name is name and value of reference is UPDATED $reference
25 |
26 |
--------------------------------------------------------------------------------
/tests/docsexample/12.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Docs Test 12
3 | --FILE--
4 | getArguments();
14 |
15 | $args[0] = "NEW {$args[0]}";
16 | $args[1] = "NEW {$args[1]}";
17 | $args[2] = "NEW {$args[2]}";
18 |
19 | $newArgs = array();
20 | $newArgs[0] = $args[0];
21 | $newArgs[1] = & $args[1];//the reference is kept
22 | $newArgs[2] = $args[2];//newArgs carry a copy of $args[2], the advice won't be able to update it's value
23 |
24 | $joinpoint->setArguments($newArgs);
25 | };
26 |
27 | aop_add_before('callMe()', $advice);
28 |
29 | $name = "name";
30 | $reference = "reference";
31 | $reference2 = "reference2";
32 | callMe($name, $reference, $reference2);
33 | echo "After the method execution, value of name is $name, reference is $reference and reference2 is $reference2";
34 |
35 | ?>
36 | --EXPECT--
37 | NEW name, NEW reference and NEW reference2. After the method execution, value of name is name, reference is M - NEW reference and reference2 is NEW reference2
38 |
39 |
--------------------------------------------------------------------------------
/tests/docsexample/13.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Docs Test 13
3 | --FILE--
4 | getArguments();
14 | $args[0] = "NEW {$args[0]}";
15 | $args[1] = "NEW {$args[1]}";
16 | $args[2] = "NEW {$args[2]}";
17 | $joinpoint->setArguments($args);
18 | };
19 |
20 | aop_add_before('callMe()', $advice);
21 |
22 | $name = "name";
23 | $reference = "reference";
24 | $reference2 = "reference2";
25 | callMe($name, $reference, $reference2);
26 | echo "After the method execution, value of name is $name, reference is $reference and reference2 is $reference2";
27 |
28 | ?>
29 | --EXPECT--
30 | NEW name, NEW reference and NEW reference2. After the method execution, value of name is name, reference is M - NEW reference and reference2 is M - NEW reference2
31 |
32 |
33 |
--------------------------------------------------------------------------------
/tests/docsexample/14.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Docs Test 14
3 | --FILE--
4 | text = "some text";
11 | return $this->text;
12 | }
13 |
14 | public function echoText ()
15 | {
16 | echo $this->text;
17 | }
18 | }
19 |
20 | $advice = function (AopJoinPoint $joinpoint) {
21 | //You're asking explicitely for the reference
22 | $result = & $joinpoint->getReturnedValue();
23 | //Updating the value of the reference
24 | $result = "This is the new text";
25 | };
26 |
27 | aop_add_after("Writer::getText()", $advice);
28 |
29 | $writer = new Writer();
30 | $text = $writer->getText();
31 | $writer->echoText();
32 |
33 | ?>
34 | --EXPECT--
35 | This is the new text
36 |
37 |
--------------------------------------------------------------------------------
/tests/docsexample/15.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Docs Test 15
3 | --FILE--
4 | text = "some text";
11 | return $this->text;
12 | }
13 |
14 | public function echoText ()
15 | {
16 | echo $this->text;
17 | }
18 | }
19 |
20 | $advice = function (AopJoinPoint $joinpoint) {
21 | //You're NOT asking explicitely for the reference
22 | $result = $joinpoint->getReturnedValue();
23 | //The returned value of the trigerring method won't be updated
24 | $result = "This is the new text";
25 | };
26 |
27 | aop_add_after("Writer::getText()", $advice);
28 |
29 | $writer = new Writer();
30 | $text = $writer->getText();
31 | $writer->echoText();
32 |
33 | ?>
34 | --EXPECT--
35 | some text
36 |
37 |
--------------------------------------------------------------------------------
/tests/docsexample/16.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | An advice that knows you're dealing with an object's property
3 | --FILE--
4 | secretStuff = 'secret';
20 | }
21 |
22 | public function say ()
23 | {
24 | echo $this->publicStuff;
25 | }
26 | }
27 |
28 | //the advice is a simple function
29 | $paparazzi = new Paparazzi();
30 | $paparazzi_informer = function () use ($paparazzi)
31 | {
32 | $paparazzi->alert();
33 | };
34 |
35 | aop_add_before('Celebrity->*Stuff', $paparazzi_informer);
36 |
37 | $CynthiaBellulla = new Celebrity();
38 | $CynthiaBellulla->act();
39 | echo $CynthiaBellulla->say();
40 | ?>
41 | --EXPECT--
42 | Celebrity will act or say something !Celebrity will act or say something !public thinking
43 |
--------------------------------------------------------------------------------
/tests/docsexample/17.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | An advice that is interested only in properties writing
3 | --FILE--
4 | secretStuff;
20 |
21 | //Writing the new value.
22 | $this->secretStuff = 'secret';
23 | }
24 | }
25 |
26 | //the advice is a simple function
27 | $paparazzi = new Paparazzi();
28 | $paparazzi_informer = function () use ($paparazzi)
29 | {
30 | $paparazzi->alert();
31 | };
32 | //will be triggered before writing the property privateStuff
33 | aop_add_before('write Celebrity->secretStuff', $paparazzi_informer);
34 |
35 | $CynthiaBellulla = new Celebrity();
36 | $CynthiaBellulla->act();
37 | ?>
38 | --EXPECT--
39 | Celebrity secretly act on something !
40 |
41 |
--------------------------------------------------------------------------------
/tests/docsexample/18.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | An advice that knows what happened on the hooked properties
3 | --FILE--
4 | name = $name;
22 | }
23 |
24 | public function getName ()
25 | {
26 | return $this->name;
27 | }
28 |
29 | public function act ()
30 | {
31 | //Reads the property (won't trigger the pointcut as it's a read operation)
32 | $oldValue = $this->secret;
33 |
34 | //Writing the new value.
35 | $this->secret = 'shoping at london';
36 | }
37 | }
38 |
39 | //the advice is a simple function
40 | $paparazzi = new Paparazzi();
41 | $paparazzi_informer = function (AopJoinPoint $aop_tjp) use ($paparazzi)
42 | {
43 | if ($aop_tjp->getKindOfAdvice() === AOP_KIND_BEFORE_READ_PROPERTY) {
44 | return;//we don't care if the value is just readed
45 | } elseif ($aop_tjp->getKindOfAdvice() === AOP_KIND_BEFORE_WRITE_PROPERTY) {
46 | $paparazzi->shoot($aop_tjp->getObject()->getName(),
47 | $aop_tjp->getAssignedValue(),
48 | $aop_tjp->getPropertyName()
49 | );
50 | }
51 | };
52 |
53 | //will be triggered before writing the property privateStuff
54 | aop_add_before('Celebrity->secret', $paparazzi_informer);
55 |
56 | $CynthiaBellulla = new Celebrity('Cynthia Bellula');
57 | $CynthiaBellulla->act();
58 | ?>
59 | --EXPECT--
60 | I'm taking pictures of Cynthia Bellula doing some shoping at london (that's supposed to be secret)
61 |
--------------------------------------------------------------------------------
/tests/docsexample/19.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | An advice that updates the assigned value of a property
3 | --FILE--
4 | getAssignedValue();
13 | if ($assigned !== 'PHP') {
14 | $assigned .= ' and PHP';
15 | }
16 | };
17 |
18 | //will be triggered before writing the property privateStuff
19 | aop_add_before('write Developper->preferences', $spread_the_love);
20 |
21 | $developper = new Developper();
22 | $developper->preferences = 'Java';
23 |
24 | echo "This developper loves ", $developper->preferences;
25 | ?>
26 | --EXPECT--
27 | This developper loves Java and PHP
28 |
--------------------------------------------------------------------------------
/tests/docsexample/2.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Docs Test 2
3 | --FILE--
4 | getArguments();
16 | if ($args[0] === null) {
17 | $args[0] = 'anyone';
18 | $object->setArguments($args);
19 | }
20 | }
21 |
22 | aop_add_before('MyServices::doStuff()', 'adviceToUpdateArguments');
23 |
24 | $services = new MyServices();
25 | $services->doStuff(null);
26 |
27 | ?>
28 | --EXPECT--
29 | I'll do my best stuff for anyone !
30 |
31 |
--------------------------------------------------------------------------------
/tests/docsexample/21.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | setAssignedValue
3 | --FILE--
4 | getAssignedValue();
13 |
14 | if ($assigned !== 'PHP') {
15 | $assigned .= ' and PHP';
16 | }
17 |
18 | $aop_tjp->setAssignedValue($assigned);
19 | };
20 |
21 | //will be triggered before writing the property privateStuff
22 | aop_add_before('write Developper->preferences', $spread_the_love);
23 |
24 | $developper = new Developper();
25 | $loveWhat = 'Python';
26 | $developper->preferences = $loveWhat;
27 |
28 | echo "This developper loves ", $developper->preferences;
29 | echo ", Yes, $loveWhat";
30 | ?>
31 | --EXPECT--
32 | This developper loves Python and PHP, Yes, Python
33 |
34 |
--------------------------------------------------------------------------------
/tests/docsexample/22.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | First doc example in aop_add_after in phpdoc
3 | --FILE--
4 | getReturnedValue(), "\n";
7 | };
8 |
9 | class Calculator
10 | {
11 | public function __construct($initialValue = 0)
12 | {
13 | $this->total = $initialValue;
14 | }
15 |
16 | public function add($number)
17 | {
18 | return $this->total += $number;
19 | }
20 | }
21 |
22 | aop_add_after('Calculator->add()', $advice);
23 |
24 | $calculator = new Calculator();
25 | $calculator->add(4);
26 | $calculator->add(2);
27 | $calculator->add(1);
28 | ?>
29 | --EXPECT--
30 | The function returned the value 4
31 | The function returned the value 6
32 | The function returned the value 7
33 |
34 |
--------------------------------------------------------------------------------
/tests/docsexample/23.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Pointcut syntax for functions
3 | --FILE--
4 | getFunctionName(), " -> foo()\n"; });
74 | aop_add_before('foo*()', function (\AopJoinPoint $jp) { echo $jp->getFunctionName(), " -> foo*()\n"; });
75 | aop_add_before('*bar()', function (\AopJoinPoint $jp) { echo $jp->getFunctionName(), " -> *bar()\n"; });
76 | aop_add_before('**\\foo()', function (\AopJoinPoint $jp) { echo $jp->getFunctionName(), " -> **\\foo()\n";});
77 | aop_add_before('foo\\bar()', function (\AopJoinPoint $jp) {echo $jp->getFunctionName(), " -> foo\\bar()\n";});
78 | aop_add_before('foo\\b*()', function (\AopJoinPoint $jp) {echo $jp->getFunctionName(), " -> foo\\b*()\n";});
79 | aop_add_before('foobar*\\*()', function (\AopJoinPoint $jp) {echo $jp->getFunctionName(), " -> foobar*\\*()\n";});
80 | aop_add_before('*\\*\\bar()', function (\AopJoinPoint $jp) { echo $jp->getFunctionName(), " -> *\\*\\bar()\n";});
81 | aop_add_before('StartWithFoo*\\**\\bar()', function (\AopJoinPoint $jp) { echo $jp->getFunctionName(), " -> StartWithFoo*\\**\\bar()\n";});
82 |
83 | $object = new \Object();
84 | \foo();
85 | \Foo();
86 | \fOo();
87 | $object->foo();
88 | \fooo();
89 | \fooBar();
90 | \bar();
91 | \foooBar();
92 | \someBar();
93 | \bar\foo();
94 | \foo\foo();
95 | \foo\bar();
96 | \bar\bar();
97 | \foo\bigbar();
98 | \foo\barFooBar();
99 | \foo\bar\bar();
100 | \foobar\anything();
101 | \foobarAnything\foo();
102 | \foobar\foo\bar();
103 | \foobar\foo\foobar();
104 | \some\longer\foo\bar();
105 | \startWithFoo\bar();
106 | \StartWithFoo\foo();
107 | \StartWITHFoo\bar2();
108 | \startWithFooSomething\anything\anything_else\foo();
109 | \startWithFooSomething\anything\anything_else\bar();
110 | }
111 | ?>
112 | --EXPECT--
113 | foo -> foo()
114 | foo -> foo*()
115 | foo -> **\foo()
116 | foo -> foo()
117 | foo -> foo*()
118 | foo -> **\foo()
119 | foo -> foo()
120 | foo -> foo*()
121 | foo -> **\foo()
122 | fooo -> foo*()
123 | foobar -> foo*()
124 | foobar -> *bar()
125 | bar -> *bar()
126 | foooBar -> foo*()
127 | foooBar -> *bar()
128 | someBar -> *bar()
129 | bar\foo -> **\foo()
130 | Foo\foo -> **\foo()
131 | Foo\bar -> foo\bar()
132 | Foo\bar -> foo\b*()
133 | Foo\bigbar -> foo\b*()
134 | Foo\barfoobar -> foo\b*()
135 | foo\bar\bar -> *\*\bar()
136 | foobar\anything -> foobar*\*()
137 | foobarAnything\foo -> **\foo()
138 | foobarAnything\foo -> foobar*\*()
139 | foobar\foo\bar -> *\*\bar()
140 | startWithFoo\bar -> StartWithFoo*\**\bar()
141 | startWithFoo\foo -> **\foo()
142 | startWithFooSomething\anything\anything_else\foo -> **\foo()
143 | startWithFooSomething\anything\anything_else\bar -> StartWithFoo*\**\bar()
144 |
--------------------------------------------------------------------------------
/tests/docsexample/24.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Pointcut syntax for methods
3 | --FILE--
4 | bar()', $advice1);
25 | aop_add_before('Foo->*bar()', $advice2);
26 | aop_add_before('Foo->bar*()', $advice3);
27 | $foo = new \Foo();
28 | $namespaceFoo_Foo = new \namespaceFoo\foo();
29 |
30 | $foo->bar();
31 | $foo->Bar();
32 | $namespaceFoo_Foo->bar();
33 | $foo->fooBar();
34 | $foo->Foobar();
35 | $namespaceFoo_Foo->fooBar();
36 | $namespaceFoo_Foo->fooBar();
37 | }
38 | ?>
39 | --EXPECT--
40 | 12312322
41 |
--------------------------------------------------------------------------------
/tests/docsexample/25.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test of method syntax for pointcuts
3 | --FILE--
4 | callingBarFoo {\n";
12 | $this->barFoo();
13 | echo "}\n";
14 | }
15 | private function privateBarFoo() {}
16 | public function callingPrivateBarFoo() {
17 | $this->privateBarFoo();
18 | }
19 | }
20 | }
21 | namespace namespaceFoo {
22 | class Foo {
23 | public function bar () {}
24 | public function fooBar () {}
25 | public function callingFooBar () {
26 | $this->fooBar();
27 | }
28 | public function callingFoo_FooBar () {
29 | echo "While in namespaceFoo_callingFoo_FooBar {\n";
30 | $foo = new \Foo();
31 | $foo->fooBar();
32 | echo "}\n";
33 | }
34 | }
35 | }
36 |
37 | namespace Test {
38 |
39 | aop_add_before('Foo->bar()', function (\AopJoinPoint $jp) {
40 | echo $jp->getClassName(), '->', $jp->getMethodName(), " => Foo->bar()\n";
41 | });
42 | aop_add_before('Foo->*bar()', function (\AopJoinPoint $jp) {
43 | echo $jp->getClassName(), '->', $jp->getMethodName(), " => Foo->*bar()\n";
44 | });
45 | aop_add_before('foo->bar*()', function (\AopJoinPoint $jp) {
46 | echo $jp->getClassName(), '->', $jp->getMethodName(), " => foo->bar*()\n";
47 | });
48 | aop_add_before('foo->*bar*()', function (\AopJoinPoint $jp) {
49 | echo $jp->getClassName(), '->', $jp->getMethodName(), " => foo->*bar*()\n";
50 | });
51 |
52 | $foo = new \Foo();
53 | $namespaceFoo_Foo = new \namespaceFoo\foo();
54 |
55 | $foo->bar();
56 | $foo->Bar();
57 | $namespaceFoo_Foo->bar();
58 | $foo->fooBar();
59 | $foo->Foobar();
60 | $namespaceFoo_Foo->fooBar();
61 | $namespaceFoo_Foo->fooBar();
62 | $foo->barFoo();
63 | $foo->BArFoO();
64 | $foo->callingBarFoo();
65 | $namespaceFoo_Foo->callingFooBar();
66 | $namespaceFoo_Foo->callingFoo_FooBar();
67 | }
68 | ?>
69 | --EXPECT--
70 | Foo->bar => Foo->bar()
71 | Foo->bar => Foo->*bar()
72 | Foo->bar => foo->bar*()
73 | Foo->bar => foo->*bar*()
74 | Foo->bar => Foo->bar()
75 | Foo->bar => Foo->*bar()
76 | Foo->bar => foo->bar*()
77 | Foo->bar => foo->*bar*()
78 | Foo->fooBar => Foo->*bar()
79 | Foo->fooBar => foo->*bar*()
80 | Foo->fooBar => Foo->*bar()
81 | Foo->fooBar => foo->*bar*()
82 | Foo->barFoo => foo->bar*()
83 | Foo->barFoo => foo->*bar*()
84 | Foo->barFoo => foo->bar*()
85 | Foo->barFoo => foo->*bar*()
86 | Foo->callingBarFoo => foo->*bar*()
87 | While in Foo->callingBarFoo {
88 | Foo->barFoo => foo->bar*()
89 | Foo->barFoo => foo->*bar*()
90 | }
91 | While in namespaceFoo_callingFoo_FooBar {
92 | Foo->fooBar => Foo->*bar()
93 | Foo->fooBar => foo->*bar*()
94 | }
95 |
--------------------------------------------------------------------------------
/tests/docsexample/3.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Docs Test 3
3 | --FILE--
4 | doStuff();
21 |
22 | ?>
23 | --EXPECT--
24 | Did some stuff !
25 | do my best stuff !
26 |
27 |
--------------------------------------------------------------------------------
/tests/docsexample/4.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Docs Test 4
3 | --FILE--
4 | getReturnedValue();
15 | $returnValue = str_replace('best', 'very best', $returnValue);
16 | $joinpoint->setReturnedValue($returnValue);
17 | };
18 |
19 | aop_add_after('MyServices::doStuff()', $advice);
20 |
21 | $services = new MyServices();
22 | echo $services->doStuff();
23 |
24 | ?>
25 | --EXPECT--
26 | doing my very best stuff !
27 |
28 |
--------------------------------------------------------------------------------
/tests/docsexample/5.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Docs Test 5
3 | --FILE--
4 | getArguments();
7 | if ($joinpoint->getReturnedValue() === false) {
8 | throw new Exception("Cannot read from file '{$args[0]}'");
9 | }
10 | };
11 |
12 | aop_add_after('file_get_contents()', $advice);
13 |
14 | try {
15 | @file_get_contents('foo file that does not exists');
16 | } catch (Exception $e) {
17 | echo $e->getMessage();
18 | }
19 |
20 | ?>
21 | --EXPECT--
22 | Cannot read from file 'foo file that does not exists'
23 |
24 |
--------------------------------------------------------------------------------
/tests/docsexample/6.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Docs Test 6
3 | --FILE--
4 | doStuff('you');
25 |
26 | ?>
27 | --EXPECT--
28 | I'll do the worst stuff I can to everyone ... mouhahahahaha !
29 |
30 |
--------------------------------------------------------------------------------
/tests/docsexample/7.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Docs Test 7
3 | --FILE--
4 | getArguments();
18 | echo "I'll do the worst stuff I can to {$args[0]} ! ... mouhahahahaha !";
19 | }
20 | }
21 |
22 | $evil = new Evil();
23 | aop_add_around('MyGoodServices::doStuff()', array($evil, 'advice'));
24 |
25 | $services = new MyGoodServices();
26 | $services->doStuff('you');
27 |
28 | ?>
29 | --EXPECT--
30 | I'll do the worst stuff I can to you ! ... mouhahahahaha !
31 |
32 |
--------------------------------------------------------------------------------
/tests/docsexample/8.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Docs Test 8
3 | --FILE--
4 | getArguments();
22 | echo " {$args[0]} by {$args[1]} equals [";
23 | try {
24 | echo $joinpoint->process();//asks for the joinpoint to be processed as normal
25 | } catch (DivideByZeroException $e) {
26 | echo "Infinity";
27 | }
28 | echo "]";//do stuff after
29 | };
30 |
31 | aop_add_around('DivideServices::divide()', $advice);
32 |
33 | $services = new DivideServices();
34 | $services->divide(4, 2);
35 | $services->divide(4, 0);
36 |
37 | ?>
38 | --EXPECT--
39 | 4 by 2 equals [2] 4 by 0 equals [Infinity]
40 |
41 |
--------------------------------------------------------------------------------
/tests/docsexample/9.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Docs Test 9
3 | --FILE--
4 | getArguments();
16 | if ($args[0] === null) {
17 | $args[0] = 'anyone';
18 | $object->setArguments($args);
19 | }
20 | $object->process();
21 | }
22 |
23 | aop_add_around('MyServices::doStuff()', 'adviceUpdatingArguments');
24 |
25 | $services = new MyServices();
26 | $services->doStuff(null);
27 |
28 | ?>
29 | --EXPECT--
30 | I'll do my best stuff for anyone !
31 |
32 |
--------------------------------------------------------------------------------
/tests/exception/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Exception in method caught
3 | --FILE--
4 | process();});
13 | $test = new mytest();
14 | try {
15 | echo $test->test();
16 | } catch (Exception $e) {
17 | echo "catch".$e->getMessage();
18 | }
19 |
20 | ?>
21 | --EXPECT--
22 | catchexception
23 |
--------------------------------------------------------------------------------
/tests/getargs/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | getArguments return caught method call arguments
3 | --FILE--
4 | getArguments());$pObj->process(); });
13 | $test = new mytest();
14 | $test->test("first");
15 |
16 | ?>
17 | --EXPECT--
18 | array(1) {
19 | [0]=>
20 | string(5) "first"
21 | }
22 | intest
23 |
--------------------------------------------------------------------------------
/tests/getargs/002.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | getArguments return method caught arguments (in all arounder)
3 | --FILE--
4 | getArguments());$pObj->process(); });
13 | aop_add_around("mytest::test()", function ($pObj) {var_dump($pObj->getArguments());$pObj->process(); });
14 | $test = new mytest();
15 | $test->test("first");
16 |
17 | ?>
18 | --EXPECT--
19 | array(1) {
20 | [0]=>
21 | string(5) "first"
22 | }
23 | array(1) {
24 | [0]=>
25 | string(5) "first"
26 | }
27 | intest
28 |
--------------------------------------------------------------------------------
/tests/getthis/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Method getTriggeringObject can overload public data
3 | --FILE--
4 | data;
10 | }
11 | }
12 |
13 | aop_add_around("A::test()", function ($pObj) {$pObj->getObject()->data="overload"; return "[".$pObj->process()."]";});
14 | $test = new A();
15 | echo $test->test();
16 |
17 | ?>
18 | --EXPECT--
19 | [testoverload]
20 |
--------------------------------------------------------------------------------
/tests/getthis/002.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | In function context getTriggeringObject return null
3 | --FILE--
4 | getObject()!=null) {
12 | echo "error";
13 | } else {
14 | echo "OK";
15 | }
16 | return "[".$pObj->process()."]";});
17 | echo test();
18 |
19 | ?>
20 | --EXPECT--
21 | OK[test]
22 |
--------------------------------------------------------------------------------
/tests/inheritance/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Not Parent class, not caucht
3 | --FILE--
4 | process()."]";});
18 | $test = new B();
19 | echo $test->test();
20 |
21 | ?>
22 | --EXPECT--
23 | test
24 |
--------------------------------------------------------------------------------
/tests/inheritance/002.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Herited class is caught (with selector on parent)
3 | --FILE--
4 | process()."]";});
15 | $test = new B();
16 | echo $test->test();
17 |
18 | ?>
19 | --EXPECT--
20 | [test]
21 |
--------------------------------------------------------------------------------
/tests/inheritance/003.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Herited class is caught (with selector on child)
3 | --FILE--
4 | process()."]";});
15 | $test = new B();
16 | echo $test->test();
17 |
18 | ?>
19 | --EXPECT--
20 | [test]
21 |
--------------------------------------------------------------------------------
/tests/inheritance/005.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Herited class is caught (with selector on interface on parent)
3 | --FILE--
4 | process()."]";});
15 | $test = new B();
16 | echo $test->test();
17 |
18 | ?>
19 | --EXPECT--
20 | [test]
21 |
--------------------------------------------------------------------------------
/tests/inheritance/006.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Herited class is caught (with selector on interface on child)
3 | --FILE--
4 | process()."]";});
18 | aop_add_around("IB::test()", function ($pObj) {return "[".$pObj->process()."]";});
19 | aop_add_around("IC::test()", function ($pObj) {return "[".$pObj->process()."]";});
20 | aop_add_around("ID::test()", function ($pObj) {return "[".$pObj->process()."]";});
21 | $test = new B();
22 | echo $test->test();
23 |
24 | ?>
25 | --EXPECT--
26 | [[[[test]]]]
27 |
--------------------------------------------------------------------------------
/tests/inheritance/007.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Inheritance of interfaces are caught (with selector on parent interface)
3 | --FILE--
4 | process()."]";});
16 | $test = new B();
17 | echo $test->test();
18 |
19 | ?>
20 | --EXPECT--
21 | [test]
22 |
--------------------------------------------------------------------------------
/tests/ini_directives/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Tests if the directive aop.enable is correctly handled
3 | --FILE--
4 |
28 | --EXPECT--
29 | aop is enabled
30 | I'm foo
31 | After foo
32 | aop is now disabled
33 | I'm foo
34 | But you can still register new aspects
35 | I'm foo
36 | Aop is now enabled
37 | I'm foo
38 | After foo
39 | After foo
40 |
--------------------------------------------------------------------------------
/tests/issues/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | No segfault with selector just *
3 | --FILE--
4 |
14 | --EXPECTF--
15 | Fatal error: The given pointcut is invalid. You must specify a function call, a method call or a property operation %s
16 |
17 |
--------------------------------------------------------------------------------
/tests/issues/002.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Testing that the use of static is still enabled
3 | --FILE--
4 | update(1);
18 | ?>
19 | --EXPECT--
20 | I'm index
21 |
--------------------------------------------------------------------------------
/tests/issues/003.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Validate that aop does not disturb create_function
3 | --FILE--
4 |
8 | --EXPECT--
9 | ln(2) + ln(2) = 1.3862943611199
10 |
--------------------------------------------------------------------------------
/tests/issues/004.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Exception propagation is not correct
3 | --FILE--
4 | getFunctionName();
18 | try {
19 | $obj->process();
20 | } catch(AdminDeniedException $e) {
21 | echo "no privilige to access $method\n";
22 | }
23 | }
24 |
25 | aop_add_before('doAdmin*()' , 'adviceForDoAdmin');
26 | aop_add_around('doAdmin*()', 'adviceForException');
27 |
28 | try {
29 | doAdminStuff();
30 | } catch(Exception $e) {
31 | echo "unknown exception";
32 | }
33 | ?>
34 | --EXPECT--
35 | unknown exception
36 |
--------------------------------------------------------------------------------
/tests/issues/005.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Exceptions thrown by a before is caught by an around
3 | --FILE--
4 | getFunctionName();
18 | try {
19 | $obj->process();
20 | } catch(AdminDeniedException $e) {
21 | echo "no privilege to access $method\n";
22 | }
23 | }
24 |
25 | aop_add_around('doAdmin*()', 'adviceForException');
26 | aop_add_before('doAdmin*()' , 'adviceForDoAdmin');
27 |
28 | try {
29 | doAdminStuff();
30 | } catch(Exception $e) {
31 | echo "unknown exception";
32 | }
33 | ?>
34 | --EXPECT--
35 | no privilege to access doAdminStuff
36 |
--------------------------------------------------------------------------------
/tests/issues/006.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | extract symbol table reset after method call
3 | --FILE--
4 | '1','var2'=>'2');
8 | extract($test);
9 | var_dump(get_defined_vars());
10 | $this->internal();
11 | var_dump(get_defined_vars());
12 |
13 | }
14 |
15 | public function internal () {
16 |
17 | }
18 | }
19 |
20 |
21 | $test = new test();
22 |
23 | $test->extract();
24 | ?>
25 | --EXPECT--
26 | array(3) {
27 | ["test"]=>
28 | array(2) {
29 | ["var1"]=>
30 | string(1) "1"
31 | ["var2"]=>
32 | string(1) "2"
33 | }
34 | ["var1"]=>
35 | string(1) "1"
36 | ["var2"]=>
37 | string(1) "2"
38 | }
39 | array(3) {
40 | ["test"]=>
41 | array(2) {
42 | ["var1"]=>
43 | string(1) "1"
44 | ["var2"]=>
45 | string(1) "2"
46 | }
47 | ["var1"]=>
48 | string(1) "1"
49 | ["var2"]=>
50 | string(1) "2"
51 | }
52 |
--------------------------------------------------------------------------------
/tests/issues/007.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | private method and properties in parent class
3 | --FILE--
4 | test;
14 | }
15 | private $container;
16 | public function write ($test) {
17 | $this->container = $test;
18 | echo '['.$this->container.']';
19 | }
20 | }
21 |
22 |
23 | class C extends B {
24 |
25 | }
26 | aop_add_before ("read ControllerTest::tttt", function () {});
27 |
28 | $b = new C ();
29 | $b->test();
30 |
31 |
32 | aop_add_before("write testsets->testse", function () {
33 |
34 |
35 | });
36 |
37 | $b->write ('test');
38 | ?>
39 | --EXPECT--
40 | test[test]
41 |
--------------------------------------------------------------------------------
/tests/issues/008.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Issue 34
3 | --FILE--
4 |
29 | --EXPECT--
30 | advice1 done function1 advice2 done function2
31 |
--------------------------------------------------------------------------------
/tests/issues/009.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Issue 37 on GitHub
3 | --FILE--
4 | process();
17 | }
18 | }
19 |
20 | $oForm = new Form();
21 | $oCsrf = new Csrf();
22 | aop_add_around('Form->render()', array($oCsrf, 'aroundFormRender'));
23 | echo $oForm->render();
24 | echo 'bar';
25 | --EXPECT--
26 | bar
27 |
--------------------------------------------------------------------------------
/tests/issues/010.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Issue 58 on GitHub
3 | --SKIPIF--
4 | skip "Bad test, to be corrected"
5 | --FILE--
6 | render()', array($oCsrf, 'aroundFormRender'));
24 | echo $oForm->render();
25 | echo 'bar';
26 | --EXPECTF--
27 | Fatal error: Uncaught exception 'Exception' with message 'bar' in %sbar
28 |
29 |
30 |
--------------------------------------------------------------------------------
/tests/issues/011.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Issue 58 on GitHub
3 | --FILE--
4 | render()', array($oCsrf, 'aroundFormRender'));
22 | try {
23 | echo $oForm->render();
24 | } catch (Exception $e) {
25 | echo "catch !";
26 | }
27 | echo 'bar';
28 | --EXPECT--
29 | catch !bar
30 |
--------------------------------------------------------------------------------
/tests/issues/47.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | getPropertyValue with private properties
3 | --SKIPIF--
4 | skip "Bad test, to be corrected"
5 | --FILE--
6 | bar;
11 | }
12 | }
13 |
14 | aop_add_before('Foo->bar', function(AopJoinPoint $jp) {
15 | echo $jp->getPropertyValue();
16 | });
17 |
18 | $foo = new Foo();
19 | $foo->test();
20 | /*
21 | $test = $foo->bar;
22 | $foo->bar = "test";
23 | $foo->bar = "test2";
24 | */
25 |
26 | ?>
27 | --EXPECT--
28 | origorigtest
29 |
30 |
--------------------------------------------------------------------------------
/tests/issues/47_2.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | getPropertyValue with protected properties
3 | --SKIPIF--
4 | skip "Bad test, to be corrected"
5 | --FILE--
6 | bar', function(AopJoinPoint $jp) {
12 | echo $jp->getPropertyValue();
13 | });
14 |
15 | $foo = new Foo();
16 | $test = $foo->bar;
17 | $foo->bar = "test";
18 | $foo->bar = "test2";
19 |
20 | ?>
21 | --EXPECT--
22 | origorigtest
23 |
24 |
--------------------------------------------------------------------------------
/tests/issues/52.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Absolute namespaces
3 | --FILE--
4 | get()', function(){echo "not root"; });
14 | aop_add_before ('\Mon\Plugin\Config->get()', function(){echo "root";});
15 | $config = new Mon\Plugin\Config();
16 | $config->get();
17 | }
18 | ?>
19 | --EXPECT--
20 | not rootrootget
21 |
--------------------------------------------------------------------------------
/tests/issues/52_2.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Absolute namespaces
3 | --FILE--
4 | get*()', function(){echo "not root"; });
14 | aop_add_before ('\Mon\Plugin\Conf*->get*()', function(){echo "root";});
15 | $config = new Mon\Plugin\Config();
16 | $config->get();
17 | }
18 | ?>
19 | --EXPECT--
20 | not rootrootget
21 |
--------------------------------------------------------------------------------
/tests/issues/65.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Absolute namespaces in functions
3 | --FILE--
4 |
18 | --EXPECT--
19 | not rootrootget
20 |
--------------------------------------------------------------------------------
/tests/issues/65_2.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Absolute namespaces in functions
3 | --FILE--
4 |
18 | --EXPECT--
19 | not rootrootget
20 |
--------------------------------------------------------------------------------
/tests/joker/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Method in selector is just a Joker
3 | --FILE--
4 | process()."]";});
16 | $test = new A();
17 | echo $test->test();
18 | echo $test->test2();
19 |
20 | ?>
21 | --EXPECT--
22 | [test][test2]
23 |
--------------------------------------------------------------------------------
/tests/joker/002.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Function call with a Joker in selector
3 | --FILE--
4 | process()."]";});
11 | echo test();
12 |
13 | ?>
14 | --EXPECT--
15 | [intest]
16 |
--------------------------------------------------------------------------------
/tests/joker/003.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Method in selector is partial with a Joker
3 | --FILE--
4 | process()."]";});
21 | $test = new A();
22 | echo $test->adminTest();
23 | echo $test->adminTest2();
24 | echo $test->test3();
25 |
26 | ?>
27 | --EXPECT--
28 | [test][test2]test3
29 |
--------------------------------------------------------------------------------
/tests/joker/004.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Class in selector is partial with a Joker
3 | --FILE--
4 | process()."]";});
21 | $test = new AECT();
22 | echo $test->adminTest();
23 | echo $test->adminTest2();
24 | echo $test->test3();
25 |
26 | ?>
27 | --EXPECT--
28 | [test][test2]test3
29 |
--------------------------------------------------------------------------------
/tests/joker/005.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Class in selector is partial with a Joker
3 | --FILE--
4 | process()."]";});
21 | $test = new AECT();
22 | echo $test->adminTest();
23 | echo $test->adminTest2();
24 | echo $test->test3();
25 |
26 | ?>
27 | --EXPECT--
28 | [test][test2]test3
29 |
--------------------------------------------------------------------------------
/tests/joker/006.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Just a joker and test no bug with recursion
3 | --FILE--
4 | test();
12 | return "test2";
13 | }
14 | }
15 |
16 | aop_add_around("*()", function ($pObj) {echo $pObj->getObject()->test(); return "[".$pObj->process()."]";});
17 | $test = new A();
18 | echo $test->test();
19 | echo $test->test2();
20 | */
21 | ?>
22 | --EXPECT--
23 |
--------------------------------------------------------------------------------
/tests/joker/007.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Joker at the begining
3 | --FILE--
4 | process()."]";});
16 | $test = new A();
17 | echo $test->Atest();
18 | echo $test->Btest();
19 |
20 | ?>
21 | --EXPECT--
22 | [test][test2]
23 |
--------------------------------------------------------------------------------
/tests/joker/008.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Joker at the begining
3 | --FILE--
4 | process()."]";});
16 | $test = new BA();
17 | echo $test->Atest();
18 | echo $test->Btst();
19 |
20 | ?>
21 | --EXPECT--
22 | [test]test2
23 |
--------------------------------------------------------------------------------
/tests/joker/009.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Joker at the end
3 | --FILE--
4 | process()."]";});
13 | $test = new BA();
14 | echo $test->test();
15 |
16 | ?>
17 | --EXPECT--
18 | test
19 |
--------------------------------------------------------------------------------
/tests/keywords/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Testing if include, include_once, require and require_once are caught
3 | --SKIPIF--
4 | skip "Not Implemented Yet"
5 | --FILE--
6 | getArguments();
9 | echo "Include was called with {$arguments[0]}";
10 | });
11 |
12 | include("empty.php");
13 |
14 |
15 | aop_add_before('include_once()', function(AopJoinPoint $ajp){
16 | $arguments = $ajp->getArguments();
17 | echo "Include_once was called with {$arguments[0]}";
18 | });
19 |
20 | include_once("empty_2.php");
21 |
22 | aop_add_before('require()', function(AopJoinPoint $ajp){
23 | $arguments = $ajp->getArguments();
24 | echo "Require was called with {$arguments[0]}";
25 | });
26 |
27 | require('empty_3.php');
28 |
29 | aop_add_before('require_once()', function(AopJoinPoint $ajp){
30 | $arguments = $ajp->getArguments();
31 | echo "Require_once was called with {$arguments[0]}";
32 | });
33 |
34 | require_once('empty_4.php');
35 |
36 | ?>
37 | --EXPECT--
38 | Include was called with empty.phpInclude_once was called with empty_2.phpRequire was called with empty_3.phpRequire_once was called with empty_4.php
39 |
--------------------------------------------------------------------------------
/tests/keywords/002.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Testing if echo is hooked
3 | --SKIPIF--
4 | skip "Not Implemented Yet"
5 | --FILE--
6 | process(); echo "after"; });
12 | unset($selector);
13 | $test = new mytest();
14 | $test->test();
15 |
16 | ?>
17 | --EXPECT--
18 | beforeintestafter
19 |
--------------------------------------------------------------------------------
/tests/misc/002.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Using a variable as a selector and updating its value.
3 | --FILE--
4 | process(); echo "after"; });
12 | $selector = "foobar::foo";
13 | $test = new mytest();
14 | $test->test();
15 |
16 | ?>
17 | --EXPECT--
18 | beforeintestafter
19 |
--------------------------------------------------------------------------------
/tests/misc/003.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Trying to use an array as a selector (won't work)
3 | --FILE--
4 | process(); echo "after"; });
12 | $test = new mytest();
13 | $test->test();
14 |
15 | ?>
16 | --EXPECTF--
17 | Warning: aop_add_around() expects parameter 1 to be string, array given in %s on line 8
18 |
19 | Fatal error: aop_add_around() expects a string for the pointcut as a first argument and a callback as a second argument in %s on line 8
20 |
21 |
--------------------------------------------------------------------------------
/tests/ns/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | TU on namespace
3 | --FILE--
4 | process()."]\n";
15 | });
16 |
17 |
18 | aop_add_around('*\ns2\ns3\ns4\mytest::test()',
19 | function ($pObj) {
20 | return '2['.$pObj->process()."]\n";
21 | });
22 |
23 |
24 | aop_add_around('ns1\*\ns3\ns4\mytest::test()',
25 | function ($pObj) {
26 | return '3['.$pObj->process()."]\n";
27 | });
28 |
29 | aop_add_around('ns1\ns2\**\mytest::test()',
30 | function ($pObj) {
31 | return '4['.$pObj->process()."]\n";
32 | });
33 |
34 | aop_add_around('ns*\ns2\ns3\ns4\mytest::test()',
35 | function ($pObj) {
36 | return '5['.$pObj->process()."]\n";
37 | });
38 |
39 | aop_add_around('*1\ns2\ns3\ns4\mytest::test()',
40 | function ($pObj) {
41 | return '6['.$pObj->process()."]\n";
42 | });
43 |
44 |
45 | aop_add_around('ns1\ns2\*\mytest::test()',
46 | function ($pObj) {
47 | return '7['.$pObj->process()."]\n";
48 | });
49 | 'TEST';
50 | $test = new mytest();
51 | echo $test->test();
52 |
53 | ?>
54 | --EXPECT--
55 | 1[2[3[4[5[6[test]
56 | ]
57 | ]
58 | ]
59 | ]
60 | ]
61 |
62 |
--------------------------------------------------------------------------------
/tests/properties/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test the hook on a property
3 | --FILE--
4 | name', function (AopJoinPoint $tjp) {
11 | echo "Sir ";
12 | });
13 |
14 | $wizard = new Hero();
15 | echo $wizard->name;
16 | ?>
17 | --EXPECT--
18 | Sir Gandalf
19 |
--------------------------------------------------------------------------------
/tests/properties/002.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test the hook on a property (write only)
3 | --FILE--
4 | name', function (AopJoinPoint $tjp) {
11 | echo "Sir ";
12 | });
13 |
14 | $wizard = new Hero();
15 | echo $wizard->name;
16 | ?>
17 | --EXPECT--
18 | Gandalf
19 |
--------------------------------------------------------------------------------
/tests/properties/003.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test the hook on a property while writing data (write only)
3 | --FILE--
4 | name', function (AopJoinPoint $tjp) {
11 | echo "I shall pass";
12 | });
13 |
14 | $wizard = new Hero();
15 | $wizard->name = "Gandalf";
16 | $temp = $wizard->name;
17 | ?>
18 | --EXPECT--
19 | I shall pass
20 |
--------------------------------------------------------------------------------
/tests/properties/004.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test the hook on a property read / write
3 | --FILE--
4 | name', function (AopJoinPoint $tjp) {
11 | echo "Triggered";
12 | });
13 |
14 | $wizard = new Hero();
15 | $wizard->name = $wizard->name;
16 | ?>
17 | --EXPECT--
18 | TriggeredTriggered
19 |
--------------------------------------------------------------------------------
/tests/properties/005.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test the hook on a property after
3 | --FILE--
4 | name', function (AopJoinPoint $tjp) {
11 | echo " the Grey";
12 | });
13 |
14 | $wizard = new Hero();
15 | echo $wizard->name;
16 | ?>
17 | --EXPECT--
18 | the GreyGandalf
19 |
--------------------------------------------------------------------------------
/tests/properties/006.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Tests on read property (setReturnedValue)
3 | --FILE--
4 | setReturnedValue ("after");
11 | });
12 |
13 | $foo = new Foo ();
14 | echo '['.$foo->var1."]\n";
15 | var_dump($foo);
16 | ?>
17 | --EXPECT--
18 | [after]
19 | object(Foo)#2 (1) {
20 | ["var1"]=>
21 | string(6) "before"
22 | }
23 |
--------------------------------------------------------------------------------
/tests/properties/007.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Test the hook on a property while writing data (write only) after writing its value
3 | --FILE--
4 | name', function (AopJoinPoint $tjp) {
11 | $pObject = $tjp->getObject();
12 | $pPropertyName = $tjp->getPropertyName();
13 | echo "wrote the Hero name of ", $pObject->$pPropertyName;
14 | });
15 |
16 | $wizard = new Hero();
17 | $wizard->name = "Gandalf the Grey";
18 | --EXPECT--
19 | wrote the Hero name of Gandalf the Grey
20 |
--------------------------------------------------------------------------------
/tests/properties/008.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Scope on write and read property
3 | --FILE--
4 | public;
17 | $temp = $this->protected;
18 | $temp = $this->private;
19 | echo "\n\nREAD :\n";
20 | $this->public = null;
21 | $this->protected = null;
22 | $this->private = null;
23 | $this->ninit = null;
24 | }
25 | /* Not implement
26 | static function stouch () {
27 | $temp = self::$spublic;
28 | $temp = self::$sprotected;
29 | $temp = self::$sprivate;
30 | self::$spublic = null;
31 | self::$sprotected = null;
32 | self::$sprivate = null;
33 |
34 | }
35 | */
36 | }
37 |
38 | aop_add_before('write Hero->*', function (AopJoinPoint $tjp) {
39 | echo "empty ".$tjp->getPropertyName()."\n";
40 | });
41 |
42 | aop_add_before('public Hero->*', function (AopJoinPoint $tjp) {
43 | echo "public ".$tjp->getPropertyName()."\n";
44 | });
45 |
46 | aop_add_before('protected Hero->*', function (AopJoinPoint $tjp) {
47 | echo "protected ".$tjp->getPropertyName()."\n";
48 | });
49 |
50 | aop_add_before('private Hero->*', function (AopJoinPoint $tjp) {
51 | echo "private ".$tjp->getPropertyName()."\n";
52 | });
53 |
54 | aop_add_before('!public Hero->*', function (AopJoinPoint $tjp) {
55 | echo "!public ".$tjp->getPropertyName()."\n";
56 | });
57 |
58 | aop_add_before('static Hero->*', function (AopJoinPoint $tjp) {
59 | echo "static ".$tjp->getPropertyName()."\n";
60 | });
61 |
62 | aop_add_before('i!static Hero->*', function (AopJoinPoint $tjp) {
63 | echo "!static ".$tjp->getPropertyName()."\n";
64 | });
65 |
66 |
67 | aop_add_before('static public|private Hero->*', function (AopJoinPoint $tjp) {
68 | echo "static public|private".$tjp->getPropertyName()."\n";
69 | });
70 |
71 | $wizard = new Hero();
72 | $wizard->touch();
73 | //Hero::stouch();
74 | ?>
75 | --EXPECT--
76 | WRITE :
77 | public public
78 | !static public
79 | protected protected
80 | !public protected
81 | !static protected
82 | private private
83 | !public private
84 | !static private
85 |
86 |
87 | READ :
88 | empty public
89 | public public
90 | !static public
91 | empty protected
92 | protected protected
93 | !public protected
94 | !static protected
95 | empty private
96 | private private
97 | !public private
98 | !static private
99 | empty ninit
100 | public ninit
101 | !static ninit
102 |
103 |
--------------------------------------------------------------------------------
/tests/properties/009.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Accessing undefined properties
3 | --FILE--
4 | undefinied', function(AopJoinPoint $jp) {
12 | echo "Accessing ", $jp->getPropertyName(), "\n";
13 | });
14 |
15 | $foo = new Foo();
16 | if (! $foo->undefinied) {
17 | echo "after the PHP notice\n";
18 | }
19 |
20 | $foo->undefinied = 'new property';
21 | echo $foo->undefinied;
22 |
23 | ?>
24 | --EXPECTF--
25 | Accessing undefinied
26 |
27 | Notice: Undefined property: Foo::$undefinied in %s on line 13
28 | after the PHP notice
29 | Accessing undefinied
30 | Accessing undefinied
31 | new property
32 |
--------------------------------------------------------------------------------
/tests/properties/010.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | getPropertyValue
3 | --FILE--
4 | bar', function(AopJoinPoint $jp) {
10 | echo $jp->getPropertyValue();
11 | });
12 |
13 | $foo = new Foo();
14 | $test = $foo->bar;
15 | $foo->bar = "test";
16 | $foo->bar = "test2";
17 |
18 | ?>
19 | --EXPECT--
20 | origorigtest
21 |
--------------------------------------------------------------------------------
/tests/read_properties/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Read Property Test
3 | --FILE--
4 | _readed[] = $pObject->getPropertyName();
11 | }
12 | public function getReaded () {
13 | return $this->_readed;
14 | }
15 | }
16 |
17 | class A {
18 | public $var1 = 'tt';
19 | public $var2 = 'oo';
20 |
21 | }
22 |
23 |
24 | $tracer = new Tracer ();
25 |
26 | aop_add_before("read A::*", array ($tracer, 'touch'));
27 |
28 | $test = new A();
29 | $test->var1 = 'test';
30 | $test->var2 = 'test2';
31 | $var1 = $test->var1;
32 | $var2 = $test->var2;
33 |
34 | var_dump($tracer->getReaded());
35 |
36 | ?>
37 | --EXPECT--
38 | array(2) {
39 | [0]=>
40 | string(4) "var1"
41 | [1]=>
42 | string(4) "var2"
43 | }
44 |
--------------------------------------------------------------------------------
/tests/read_properties/003.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Read Property Test
3 | --FILE--
4 | _readed[] = $pObject->getPropertyName();
11 | }
12 | public function getReaded () {
13 | return $this->_readed;
14 | }
15 | }
16 |
17 | class A {
18 | public $var1 = 'tt';
19 | public $var2 = 'oo';
20 | }
21 |
22 |
23 | $tracer = new Tracer ();
24 |
25 | aop_add_before("read A::Var*", array ($tracer, 'touch'));
26 |
27 | $test = new A();
28 | $test->var1 = 'test';
29 | $test->var2 = 'test2';
30 | $var1 = $test->var1;
31 | $var2 = $test->var2;
32 |
33 | var_dump($tracer->getReaded());
34 |
35 |
36 | aop_add_before("read A::var*", array ($tracer, 'touch'));
37 |
38 | $test = new A();
39 | $test->var1 = 'test';
40 | $test->var2 = 'test2';
41 | $var1 = $test->var1;
42 | $var2 = $test->var2;
43 |
44 | var_dump($tracer->getReaded());
45 |
46 | ?>
47 | --EXPECT--
48 | array(0) {
49 | }
50 | array(2) {
51 | [0]=>
52 | string(4) "var1"
53 | [1]=>
54 | string(4) "var2"
55 | }
56 |
--------------------------------------------------------------------------------
/tests/scope/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Scope
3 | --FILE--
4 | process();
8 | echo "1".$toReturn."\n";
9 | return $toReturn;
10 | });
11 |
12 | aop_add_around('private A::test*()',
13 | function ($pObj) {
14 | $toReturn = $pObj->process();
15 | echo "2".$toReturn."\n";
16 | return $toReturn;
17 | });
18 |
19 | aop_add_around('protected A::test*()',
20 | function ($pObj) {
21 | $toReturn = $pObj->process();
22 | echo "3".$toReturn."\n";
23 | return $toReturn;
24 | });
25 | class A {
26 | private function testp () {
27 | return "private";
28 | }
29 |
30 | protected function testpr () {
31 | return "protected";
32 | }
33 | public function test () {
34 | $this->testp();
35 | $this->testpr();
36 | return "public";
37 | }
38 | }
39 |
40 | $a = new A();
41 | $a->test();
42 |
43 | ?>
44 | --EXPECT--
45 | 2private
46 | 3protected
47 | 1public
48 |
--------------------------------------------------------------------------------
/tests/scope/002.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Scope
3 | --FILE--
4 | process();
8 | echo "1".$toReturn."\n";
9 | return $toReturn;
10 | });
11 |
12 | aop_add_around('public|private A::test*()',
13 | function ($pObj) {
14 | $toReturn = $pObj->process();
15 | echo "2".$toReturn."\n";
16 | return $toReturn;
17 | });
18 |
19 | aop_add_around('private|protected A::test*()',
20 | function ($pObj) {
21 | $toReturn = $pObj->process();
22 | echo "3".$toReturn."\n";
23 | return $toReturn;
24 | });
25 |
26 | aop_add_around('private|public A::test*()',
27 | function ($pObj) {
28 | $toReturn = $pObj->process();
29 | echo "4".$toReturn."\n";
30 | return $toReturn;
31 | });
32 | aop_add_around('protected|private A::test*()',
33 | function ($pObj) {
34 | $toReturn = $pObj->process();
35 | echo "5".$toReturn."\n";
36 | return $toReturn;
37 | });
38 | aop_add_around('protected|public A::test*()',
39 | function ($pObj) {
40 | $toReturn = $pObj->process();
41 | echo "6".$toReturn."\n";
42 | return $toReturn;
43 | });
44 | aop_add_around('private|protected|public A::test*()',
45 | function ($pObj) {
46 | $toReturn = $pObj->process();
47 | echo "7".$toReturn."\n";
48 | return $toReturn;
49 | });
50 | class A {
51 | private function testp () {
52 | return "private";
53 | }
54 |
55 | protected function testpr () {
56 | return "protected";
57 | }
58 | public function test () {
59 | $this->testp();
60 | $this->testpr();
61 | return "public";
62 | }
63 | }
64 |
65 | $a = new A();
66 | $a->test();
67 |
68 | ?>
69 | --EXPECT--
70 | 7private
71 | 5private
72 | 4private
73 | 3private
74 | 2private
75 | 7protected
76 | 6protected
77 | 5protected
78 | 3protected
79 | 1protected
80 | 7public
81 | 6public
82 | 4public
83 | 2public
84 | 1public
85 |
--------------------------------------------------------------------------------
/tests/scope/003.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Scope with static
3 | --FILE--
4 | process();
8 | echo "1".$toReturn."\n";
9 | return $toReturn;
10 | });
11 |
12 | aop_add_around('public !static A::test*()',
13 | function ($pObj) {
14 | $toReturn = $pObj->process();
15 | echo "2".$toReturn."\n";
16 | return $toReturn;
17 | });
18 |
19 | aop_add_around('public A::test*()',
20 | function ($pObj) {
21 | $toReturn = $pObj->process();
22 | echo "3".$toReturn."\n";
23 | return $toReturn;
24 | });
25 | class A {
26 | private function testp () {
27 | return "private";
28 | }
29 |
30 | protected function testpr () {
31 | return "protected";
32 | }
33 | public function test () {
34 | $this->testp();
35 | $this->testpr();
36 | return "public";
37 | }
38 | public static function testst () {
39 | self::teststp();
40 | self::teststpr();
41 | return "staticpublic";
42 | }
43 | protected static function teststpr () {
44 | return "staticprotected";
45 | }
46 | private static function teststp () {
47 | return "staticprivate";
48 | }
49 | }
50 |
51 | $a = new A();
52 | $a->test();
53 | A::testst();
54 |
55 | ?>
56 | --EXPECT--
57 | 3public
58 | 2public
59 | 3staticpublic
60 | 1staticpublic
61 |
--------------------------------------------------------------------------------
/tests/simple/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Just an around method test (version with echo)
3 | --FILE--
4 | process(); echo "after"; });
13 | $test = new mytest();
14 | $test->test();
15 |
16 | ?>
17 | --EXPECT--
18 | beforeintestafter
19 |
--------------------------------------------------------------------------------
/tests/simple/002.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Just an around method test (version with return)
3 | --FILE--
4 | process()."]";});
13 | $test = new mytest();
14 | echo $test->test();
15 |
16 | ?>
17 | --EXPECT--
18 | [intest]
19 |
--------------------------------------------------------------------------------
/tests/simple/003.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | An around method test without call to process
3 | --FILE--
4 | test();
15 |
16 | ?>
17 | --EXPECT--
18 | nocall
19 |
--------------------------------------------------------------------------------
/tests/simple/004.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Just an around method test (version with 2 Pointcuts)
3 | --FILE--
4 | process()."}";});
13 | aop_add_around("mytest::test()", function ($pObj) {return "[".$pObj->process()."]";});
14 | $test = new mytest();
15 | echo $test->test();
16 |
17 | ?>
18 | --EXPECT--
19 | {[intest]}
20 |
--------------------------------------------------------------------------------
/tests/simple/005.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Function call (exact name)
3 | --FILE--
4 | process()."]";});
11 | echo test();
12 |
13 | ?>
14 | --EXPECT--
15 | [intest]
16 |
--------------------------------------------------------------------------------
/tests/simple/006.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Testing alternative separator for selectors (-> instead of ::)
3 | --FILE--
4 | test()", function ($pObj) {return "[".$pObj->process()."]";});
13 | $test = new mytest();
14 | echo $test->test();
15 |
16 | ?>
17 | --EXPECT--
18 | [intest]
19 |
--------------------------------------------------------------------------------
/tests/simple/007.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Testing invalid callback given to aop_add_around()
3 | --FILE--
4 | test()", array('Foo', 'bar'));
13 | $test = new mytest();
14 | echo $test->test();
15 |
16 | ?>
17 | --EXPECTF--
18 | Warning: aop_add_around() expects parameter 2 to be a valid callback, class 'Foo' not found in %s on line 9
19 |
20 | Fatal error: aop_add_around() expects a string for the pointcut as a first argument and a callback as a second argument in %s on line 9
21 |
22 |
--------------------------------------------------------------------------------
/tests/simple/008.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Testing invalid callback given to aop_add_before()
3 | --FILE--
4 | test()", array('Foo', 'bar'));
13 | $test = new mytest();
14 | echo $test->test();
15 |
16 | ?>
17 | --EXPECTF--
18 | Warning: aop_add_before() expects parameter 2 to be a valid callback, class 'Foo' not found in %s on line 9
19 |
20 | Fatal error: aop_add_before() expects a string for the pointcut as a first argument and a callback as a second argument in %s on line 9
21 |
--------------------------------------------------------------------------------
/tests/simple/009.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Testing invalid callback given to aop_add_after()
3 | --FILE--
4 | test()", array('Foo', 'bar'));
13 | $test = new mytest();
14 | echo $test->test();
15 |
16 | ?>
17 | --EXPECTF--
18 | Warning: aop_add_after() expects parameter 2 to be a valid callback, class 'Foo' not found in %s on line 9
19 |
20 | Fatal error: aop_add_after() expects a string for the pointcut as a first argument and a callback as a second argument in %s on line 9
21 |
22 |
--------------------------------------------------------------------------------
/tests/traits/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Traits test
3 | --SKIPIF--
4 | =')) echo "skip >= PHP 5.4 needed\n"; ?>
5 | --FILE--
6 | process(); echo "after"; });
19 | $test = new mytest();
20 | $test->test();
21 |
22 | ?>
23 | --EXPECT--
24 | beforeintestafter
25 |
--------------------------------------------------------------------------------
/tests/write_properties/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Write Property Test
3 | --FILE--
4 | _modified[] = $pObject->getPropertyName();
11 | }
12 | public function getModified () {
13 | return $this->_modified;
14 | }
15 | }
16 |
17 | class A {
18 |
19 |
20 | }
21 |
22 |
23 | $tracer = new Tracer ();
24 |
25 | aop_add_before("write A::*", array ($tracer, 'touch'));
26 |
27 | $test = new A();
28 | $test->var1 = 'test';
29 | $test->var2 = 'test2';
30 |
31 | var_dump($tracer->getModified());
32 |
33 | ?>
34 | --EXPECT--
35 | array(2) {
36 | [0]=>
37 | string(4) "var1"
38 | [1]=>
39 | string(4) "var2"
40 | }
41 |
--------------------------------------------------------------------------------
/tests/write_properties/002.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Write Property Test Test Recursion Loop
3 | --FILE--
4 | getPropertyName();
13 | $pValue = $pObject->getAssignedValue();
14 | $pObjectModify = $pObject->getObject();
15 | if (!isset ($this->_original[$pVarName])) {
16 | $this->_original[$pVarName] = $pObjectModify->$pVarName;
17 | }
18 | $this->_modified[$pVarName] = $pValue;
19 | if ($this->_original[$pVarName]==$this->_modified[$pVarName]) {
20 | unset ($this->_modified[$pVarName]);
21 | }
22 | }
23 |
24 | public function getModified () {
25 | return $this->_modified;
26 | }
27 | }
28 |
29 | class A {
30 |
31 |
32 | }
33 |
34 |
35 | $tracer = new Tracer ();
36 |
37 |
38 | $test = new A();
39 | $test->var1 = 'test';
40 | $test->var2 = 'test2';
41 |
42 | aop_add_before("write A::*", array ($tracer, 'touch'));
43 |
44 | $test->var1 = 'test_modified';
45 | $test->var2 = 'test_modified';
46 |
47 | $test->var1 = 'test';
48 |
49 | var_dump($tracer->getModified());
50 |
51 | ?>
52 | --EXPECT--
53 | array(1) {
54 | ["var2"]=>
55 | string(13) "test_modified"
56 | }
57 |
--------------------------------------------------------------------------------
/tests/write_properties/003.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Write Property Selector -> ->$ :: ::$
3 | --FILE--
4 | getPropertyName();
11 | $this->_modified[] = $pVarName.'1';
12 | }
13 | public function touch2 ($pObject) {
14 | $pVarName = $pObject->getPropertyName();
15 | $this->_modified[] = $pVarName.'2';
16 | }
17 | public function touch3 ($pObject) {
18 | $pVarName = $pObject->getPropertyName();
19 | $this->_modified[] = $pVarName.'3';
20 | }
21 | public function touch4 ($pObject) {
22 | $pVarName = $pObject->getPropertyName();
23 | $this->_modified[] = $pVarName.'4';
24 | }
25 | public function getModified () {
26 | return $this->_modified;
27 | }
28 | }
29 |
30 | class A {
31 |
32 |
33 | }
34 |
35 |
36 | $tracer = new Tracer ();
37 | aop_add_before("write A::*", array ($tracer, 'touch1'));
38 | aop_add_before("write A->*", array ($tracer, 'touch2'));
39 | aop_add_before("write A::$*", array ($tracer, 'touch3'));
40 | aop_add_before("write A->$*", array ($tracer, 'touch4'));
41 | $test = new A();
42 | $test->var1 = 'test';
43 | $test->var2 = 'test2';
44 |
45 | var_dump($tracer->getModified());
46 |
47 | ?>
48 | --EXPECT--
49 | array(8) {
50 | [0]=>
51 | string(5) "var11"
52 | [1]=>
53 | string(5) "var12"
54 | [2]=>
55 | string(5) "var13"
56 | [3]=>
57 | string(5) "var14"
58 | [4]=>
59 | string(5) "var21"
60 | [5]=>
61 | string(5) "var22"
62 | [6]=>
63 | string(5) "var23"
64 | [7]=>
65 | string(5) "var24"
66 | }
67 |
--------------------------------------------------------------------------------
/tests/write_properties/004.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Read / Write Property with inc or dec
3 | --FILE--
4 | var1++;
17 | ++$test->var1;
18 | $test->var1--;
19 | --$test->var1;
20 |
21 | $test->var2++;
22 | ++$test->var2;
23 | $test->var2--;
24 | --$test->var2;
25 |
26 |
27 | ?>
28 | --EXPECT--
29 | READ
30 | WRITE
31 | READ
32 | WRITE
33 | READ
34 | WRITE
35 | READ
36 | WRITE
37 | READ
38 | WRITE
39 | READ
40 | WRITE
41 | READ
42 | WRITE
43 | READ
44 | WRITE
45 |
--------------------------------------------------------------------------------
/tests/write_properties/005.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Write Property Test
3 | --FILE--
4 | getPropertyName();
11 | $this->_modified[] = $pVarName;
12 | }
13 | public function getModified () {
14 | return $this->_modified;
15 | }
16 | }
17 |
18 | class A {
19 |
20 |
21 | }
22 |
23 |
24 | $tracer = new Tracer ();
25 |
26 | aop_add_before("write A::*", array ($tracer, 'touch'));
27 |
28 | $test = new A();
29 | $test->var1 = 'test';
30 | $test->Var2 = 'test2';
31 |
32 | var_dump($tracer->getModified());
33 |
34 | ?>
35 | --EXPECT--
36 | array(2) {
37 | [0]=>
38 | string(4) "var1"
39 | [1]=>
40 | string(4) "Var2"
41 | }
42 |
--------------------------------------------------------------------------------
/tests/write_properties/006.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Write Property Test
3 | --FILE--
4 | getPropertyName();
11 | $this->_modified[] = $pVarName;
12 | }
13 | public function getModified () {
14 | return $this->_modified;
15 | }
16 | }
17 |
18 | class A {
19 |
20 |
21 | }
22 |
23 |
24 | $tracer = new Tracer ();
25 |
26 | aop_add_before("write A::V*", array ($tracer, 'touch'));
27 |
28 | $test = new A();
29 | $test->var1 = 'test';
30 | $test->Var2 = 'test2';
31 |
32 | var_dump($tracer->getModified());
33 |
34 | ?>
35 | --EXPECT--
36 | array(1) {
37 | [0]=>
38 | string(4) "Var2"
39 | }
40 |
--------------------------------------------------------------------------------
/tests/write_properties/007.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Write General API
3 | --FILE--
4 | getObject();
15 | $pProperty = $pObj->getPropertyName ();
16 | echo "B ".$pObject->$pProperty."\n";
17 | });
18 |
19 | aop_add_after('write Foo::var1', function ($pObj) {
20 | $pObject = $pObj->getObject();
21 | $pProperty = $pObj->getPropertyName ();
22 | echo "A ".$pObject->$pProperty."\n";
23 | });
24 |
25 |
26 | aop_add_around ('write Foo::var2', function ($pObj) {
27 | $pObject = $pObj->getObject();
28 | $pProperty = $pObj->getPropertyName ();
29 | echo "B ".$pObject->$pProperty."\n";
30 | $pObj->process();
31 | echo "A ".$pObject->$pProperty."\n";
32 |
33 | });
34 |
35 | aop_add_around ('write Foo::var3', function ($pObj) {});
36 |
37 | $foo = new Foo ();
38 | $foo->var1="after";
39 | $foo->var2="after";
40 | $foo->var3="after";
41 | var_dump ($foo->var3);
42 | --EXPECT--
43 | B before
44 | A after
45 | B before
46 | A after
47 | string(6) "before"
48 |
--------------------------------------------------------------------------------