├── .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 | [![Build Status](https://secure.travis-ci.org/AOP-PHP/AOP.png?branch=master)](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 <function>aop_add_after</function> 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 | --------------------------------------------------------------------------------