Transparent PHP AOP - Manual Current Version: 1.0 RC 3 - Build 2006-12-22

Guilherme Blanco

New Features of this version

Table of Contents

  1. Introduction
  2. Getting Started
    1. Installing
    2. Quick Tutorial
      1. Setting up a basic class
      2. Creating your custom code
      3. Loading basic class
    3. Testing your installation
    4. Troubleshooting
  3. What is AOP?
    1. Introduction
    2. AOP Naming Convention
      1. Aspect
      2. Advice
      3. Join Point
      4. Pointcut
      5. Weave
  4. Complete Guide
    1. Introduction
      1. Briefing
      2. Conventions
      3. How does it work?
        1. Internal Structure
    2. XML Aspect Definition (XAD)
      1. XML Aspect DTD
      2. Defining Pointcut and Advice
      3. Applying restrictions
    3. PHP Class Code
      1. Custom Pointcuts
      2. Automatic Pointcuts
    4. Application Loading
      1. Loading Class File
      2. Modifying Compile Options

1. Introduction

In a few words, Transparent PHP AOP is a set of classes that work together to emulate AOSD (Aspect Oriented Software Development).
Supporting PHP 4.3.0+ installations, the simplicity is a strong point in Transparent AOP; everything is controlled in a human-readable and easily understandable XML Aspect Definition (XAD) file.
This document explain all the resources available to you with this package. It is a short document, because of class simplicity; however, it is still a very powerful tool.

2. Getting Started

2.1. Installing

This is the best part! Look: It will not have more than one line! Here it comes:

Unzip the content of this package inside your project's folder.

Difficult, huh? ;)

2.2. Quick Tutorial

This chapter is like "Learn Transparent PHP AOP in 5 minutes" tutorials. It is simple, do not cover all features, but it is enough to developers use the basic features of this class without any problems.
In this tutorial, we will setup a class, will define an Aspect to be appplied and finally will apply it. The "Testing your installation" section will explain how to check if it worked well, and "Troubleshooting" will

2.2.1. Setting up a basic class

Suppose we have a class names Test. In our UML Class Diagram, we have this methods and properties:

+-------------------------------+
| Test                          |
+-------------------------------+
| - message: string             |
+-------------------------------+
| + Test(m: String): Test       |
| + setMessage(m: string): void |
| + getMessage(): string        |
| + display(): void             |
+-------------------------------+

So, we create the following PHP Code:

<?php

class Test {
    var $message;

    function Test($m) {
        $this->setMessage($m);
    }

    function setMessage($m) {
        $this->message = $m;
    }

    function getMessage() {
        return $this->message;
    }
    
    function display() {
        echo $this->message;
    }
}

?>

Finally, save this file in this location: AOP root folder + tutorial/class.Test.php

2.2.2. Creating your custom code

Suppose we have to track method calls, in a basic approach of a Debugger System; consider we want to include a Debugger Aspect.
To track calls, we just print the name of the function and if is in the beginning or ending of it.

The XML Aspect Definition allows you to write PHP Code to be applied in the class (Advice).
We will write 4 custom pieces of code to be merged with class Test. The XML syntax uses a simple hierarchy that the root element is an Aspect and supports one or more Pointcuts. Each Pointcut contains some attributes that define the location to be applied and as a child it comes with a CDATA node containing the PHP code.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE aspect SYSTEM "../aop.dtd">

<aspect>
    <pointcut auto="after" function="setMessage">
    <![CDATA[
        echo "End of " . __FUNCTION__ ."(\"" . $m . "\") call.<br />";
    ]]>
    </pointcut>

    <pointcut auto="after" class="Test" nfunction="display">
    <![CDATA[
        echo "End of " . __FUNCTION__ ." call.<br />";
    ]]>
    </pointcut>

    <pointcut auto="before" nfunction="display">
    <![CDATA[
        echo "Beginning of " . __FUNCTION__ ." call.<br />";
    ]]>
    </pointcut>
    
    <pointcut auto="around" function="display" class="Test">
    <![CDATA[
    	echo "<b>Message: </b>";
        proceed();
        echo "<br />";
    ]]>
    </pointcut>
</aspect>

The first pointcut is an AutoPointcut (detailed later) specific to setMessage method. Its Advice prints the name of the function and the $m local variable content.
The second pointcut apply the same Advice to all end of calls inside class Test, except in method "display".
The third pointcut is also an AutoPointcut and its Advice prints a message containing the name of the function, and it is applicable in the beginning of all methods (or functions) defined in the desirable document, but it will not be applyed to a function/method called "display". The last pointcut, another AutoPointcut will be applyed in method display inside of class Test. It will display the first line before the method commands, will execute them and after it will print the new line HTML code. The proceed(); method means the whole method content!

Save this file as debugger.xml inside the AOP root folder + tutorial directory.

2.2.3. Loading basic class

The last part of this quick tutorial explains supperficially how to apply the XAD into Original class.

Transparent PHP AOP defines a function called require_aop. It is a require_once style method that either compiles the Aspects into Class files or load already compiled files. If the compiled file does not exist, the script compiles and try to save the compiled content into a unique named file. Since version 1.0 RC3, the compiled file name is more readable, allowing the programmer to connect the original class file with the compiled class file (they will have the same name, except that the compiled will have a md5 hash after it).

NOTE: Make sure your tutorial folder has permissions for write. This is necessary to the script works correctly.

Our script loader is our application. It is reduced into a minimum possible code, to show exactly only the AOP functionality.

<?php

require_once "../func.require_aop.php";

// Loading compiled class or compiling and saving
require_aop("class.Test.php", "debugger.xml");

// Testing...
$test = new Test("George Bush");

if ($test->getMessage() != "Author") {
    $test->setMessage("Guilherme Blanco");
}

$test->display();

?>

Save this file into AOP root folder + tutorial with the index.php file name.

Try running the index.php into your server and you will see the defined Advices begin displayed in screen, as defined. If not, proceed to Troubleshooting section.

2.3. Testing your installation

Last topic we exposed a quick tutorial. It compiled the class Test with the debugger.xml aspect. As a result, it should generate a compiled file, probably named "class.Test.4f207ed29fbb1b4b06f233a9fa05c471.php". If not, it will probably have a file with a name that is the original file name plus a md5 hash plus the PHP extension. Open it in your favourite PHP editor.

If everything went ok, you'll see the defined debugger.xml code merged with class.Test.php code. For our example, it should be something like:

<?php

class Test {
    var $message;

    function Test($m) { /* AOP "before" Auto Code */ echo "Beginning of " . __FUNCTION__ ." call.<br />";
        $this->setMessage($m);
    /* AOP "after" Auto Code */ echo "End of " . __FUNCTION__ ." call.<br />"; }

    function setMessage($m) { /* AOP "before" Auto Code */ echo "Beginning of " . __FUNCTION__ ." call.<br />";
        $this->message = $m;
    /* AOP "after" Auto Code */ echo "End of " . __FUNCTION__ ."(\"" . $m . "\") call.<br />"; echo "End of " . __FUNCTION__ ." call.<br />"; }

    function getMessage() { /* AOP "before" Auto Code */ echo "Beginning of " . __FUNCTION__ ." call.<br />";
        /* AOP "after" Auto Code */ echo "End of " . __FUNCTION__ ." call.<br />";  return $this->message;
    /* AOP "after" Auto Code */ echo "End of " . __FUNCTION__ ." call.<br />"; }
    
    function display() { /* AOP "before" Auto Code */ echo "<b>Message: </b>";
        echo $this->message;
    /* AOP "after" Auto Code */ echo "<br />"; }
}

?>

Next section explains commom mistakes. If the compiled file exist and if its code does not match with above code, notify me via email (guilhermeblanco [at] hotmail [dot] com), messenger (same as email) or at PHP Classes.org Forums.

2.4. Troubleshooting

1. It appears some errors while using require_aop function?

This is probably because of your PHP version module installed in your server. Currently, Transparent PHP AOP supports versions since 4.3.0+, basically because of tokenizer functions and Regular Expressions functions. Also, it uses internally the Expat XML functions, that is built-in with your PHP module (and if you don't want it, you remove it manually).
These are the main issues that can happen. If is everything fine and you still experience errors, feel free to contact me at guilhermeblanco [at] hotmail [dot] com.

2. Every call to require_aop, appears this error: [Aspect Error]: File XXX [From Original: YYY] could not be created/loaded for write!

This happens when you do not assign permissions to read/write in the directory that compiled file is generated. Please, assign a valid CHMOD value and everything will work. If not, check if you are not exceeding your disk quota.

1. It appears some E_STRICT errors while using the package?

That's true. In PHP5 there is a E_STRICT error, that notifies commom differences between PHP4 and PHP5. This does not means that your code will not work; it just mention that the notifyed code has changed its declaration. To fix this, disable this type of error reporting.

New Troubleshooting itens will be added if encountered new user mistakes.

3. What is AOP?

Several places around Web provide more complete guides to AOSD. This Manual explains the basic idea of usage and the terminology, to help introducing interested people in AOP that want to use this package. For more explanations and references, please refer to: http://en.wikipedia.org/wiki/Aspect-oriented_programming.

3.1. Introduction

AOSD came to solve the existent problems of OOP approach. Imagine building a website, and you need to incorporate a debugging system on it. In commom OOP approach, you have to create a Debbuger class, and trace your code by editting the class code, right? So, you have a single class merging the whole system. That is not OOP, that is AOP. The only point I wrote here that is wrong, is to edit the class code. In AOP, you do not edit code, you apply what we call Advices and they are aplied without change the original class code.
You still do not understand? Ok, I will try to explain better. Instead of create a set of classes and embed their usage code inside your application module, you merge different aspects of your system in your application module, and everything will be fine.
Still don't understand? Check out WikiPedia text.

3.2. AOP Naming Convention

AOP has a special naming convention, and knowing them will help you to understand how does this approach work. Read carefully this section and the "Conventions", that will explain how does this package works based in the AOP theory.

3.2.1. Aspect

To be very formal, an Aspect is a set of Pointcuts. Explaining better, an Aspect is a perspective of your system, for example, Logging, Debugging, Benchmarking, etc.

3.2.2. Advice

An Advice is a piece of code. AOP theory divagates a lot in this point, but this is a piece of code that can be applied in a Join Point.

3.2.3. Join Point

This is a place inside original file where additionally code (Pointcut) can be defined.

3.2.4. Pointcut

A set of Advices consists in a Pointcut. It is this code that is applied in a Join Point.

3.2.5. Weave

Weave is the whole behavior of your system. Technically speaking, a Weave is a set of Aspects.

4. Complete Guide

4.1. Introduction

4.1.1. Briefing

This section tryes to explain the reasons of the existance of this class.
The origin is a conversation between the author of the package and a friend, who came with the idea to break the paradigm that it was impossible to create a complete AOP approach in PHP language. After some discussion and links popping at MSN, we found several implementations that uses external extensions, PHP5 dependency or even it's a module that must be installed on server.
Since none of these solutions match our needs, we continued discussing possibilities to solve the paradigm. More references we added, and we came up with the idea of compiling merged contents and use Tokenizer functions. This solved all our "to-be-defined" questions and allow me (the author) to start a project. My friend did not onboard it.

4.1.2. Conventions

While I was developing this package, I assigned some names to help to strict follow my idea. Since I think it's not necessary those UML diagrams (Use Case, Analisys Class, Implementation Class, Sequence) for small projects, I used some other names (different from AOP theory) to simplify my work.
Since version 1.0 RC2, I updated the whole system to follow the AOP theory.
Now, what AOP defines as a Weave, we have a class named Weave too. The same for Aspect, Pointcut (not exactly, it is called in my implementation as AutoPointcut) and Advice. The only missing point is the Join Point.
In AOP, a Join Point is a place where advice can be applied. My implementation does not have this, since XAD can refer to more than one Join Point. So, this is packed inside Pointcut class.

4.1.3. How does it work?

The idea is simple. I'll draw it using ASCII instead of pic, since I want to make this Manual a unique file, not a package. I hope you understand. Here is the approach I defined:

          +-------------------+
          |     Class File    |
          +-------------------+
                   /\
                   ||                      +---------------------+
                   ||=====================>| Compiled Class File |
                   ||                      +---------------------+
    +-----------+-------------------+
    |           |                   |
+-------+   +-------+           +-------+
|  XAD  |   |  XAD  |  .  .  .  |  XAD  |
+-------+   +-------+           +-------+

You have your class file. There, you can define CustomPointcuts (explained in details later), by adding some comment like lines.
You also define you XAD (Xml Aspect Definition), that is a XML file with a strict DTD. This is converted in a PHP Aspect structure. This structure stores 1..N Pointcuts. Each Pointcut contains a name (or its repectively auto), a possible se of classes and a set of possible methods to be applied. Finally, we have the code inside it too.
When you want to get some Advice, each Aspect is checked and is exists any Pointcut that matches with the name/auto, function (optional) and class (also optional too), its code (an instance of Advice) is returned.

4.1.3.1. Internal Structure

Technically speaking, Transparent PHP AOP is simple.
It starts by calling a custom function, require_aop. Internally, it make some conditions to check if there is at least one Aspect associated, if a compiled file exists, and, if yes, check for recent changes in original class file or in one of the associated Aspects.
If this condition is false, then it simply load the compiled class file; otherwise, start the pain!

To compile a file, the package read each XAD file into an Aspect object. This object holds a list of Pointcuts (AutoPointcuts and CustomPointcuts).
Each instance of Pointcut derived classes holds an Advice object, which contains the source code defined.

The compiler retrieves the Original Class file source and then starts its execution.
The source is then passed to the lexer, which extracts each token. The compiler does a lot of jobs, and them compile first the CustomPointcut. This is done first bacause a CustomPointcut may also have an "after" JoinPoint, that should be treated by AutoPointcuts.
After the first compilation, another call to curly braces correction is done, to correct possible statements what define a single command block.
The last compilation does the AutoPointcut merging.

The CustomPointcut compilation is done via Regular Expressions. The compiler looks for occurencies of /// Pointcut: XXX and then replace the matched item by the Advice related to that name.

AutoPointcut compilation does the hardest part.
First of all, it split the whole source code into tokens. Also, it defines a level stack, which hold the identation level in the current file.
The compiler then loops through all tokens, and it finds the class declaration, method declaration, function declaration and also function exit statements (like return).
When it finds a match, it looks for the list of attached Aspects for an Advice related to the JoinPoint in the Pointcut. Then, it replaces one by the other.

After the whole compilation, the package generated a cache file containing the orginal source file merged with the related aspects.
This compiled file is then loaded, as mentioned earlier.

4.2. XML Aspect Definition (XAD)

4.2.1. XML Aspect DTD

XAD follows a very simple DTD. It consists in a root element, an aspect. Then, it accepts one or more childs, all pointcuts.
One pointcut can have modifiers, that will be detailed later. The pointcut childen can be the following things: CDATA sections, that contains PHP code or Advice tags, that loads external PHP source.
There is a DTD available that you can attach to your XAD file to be validated. Include it and in some browsers to check if it is validated successfully.

NOTE: Since version 1.0 RC2 it is possible to merge CDATAs and Advice XAD tags, in an unlimited number of times. Older versions just accept a single child, a CDATA that contains the Advice.

A simple structure can be extracted:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE aspect SYSTEM "../aop.dtd">

<aspect>
    <pointcut ...>
    <![CDATA[
        ...
    ]]>
    </pointcut>

    ...
</aspect>
NOTE: One Aspect must have at least one Pointcut element.

4.2.2. Defining Pointcut and Advice

Previous section exposes the basic XAD definition.
To define one pointcut, it must be child of an aspect node. Then, you have its attributes, that are restrictions to be applied (defined in the next section).
An Advice is the PHP code that is relative to a Pointcut. It must be defined inside the CDATA node, defined as child node of the Pointcut XML node or an advice node, if you want to load external data.

NOTE: Since version 1.0 RC2, it is possible to define Advices not only in classes, but also in functions. This is the major improvement of this release, that also innovates bringing the possibility to load external PHP Advice code and tuning the package to follow the AOP theory more strictly.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE aspect SYSTEM "../aop.dtd">

<aspect>
    // [CORRECT] This code will work!
    <pointcut ...>
    <![CDATA[
        echo "Here!<br />";
    ]]>
    </pointcut>

    // [WRONG] This will not work...
    <pointcut ...>
        echo "Here too!<br />";
    </pointcut>
</aspect>

// [WRONG] This will not work too...
<pointcut auto="before">
<![CDATA[
    echo "And here again!<br />";
]]>
</pointcut>

Since version 1.0 RC2, Transparent PHP AOP enabled you to load external PHP Advice code. To make things happen, you have to define it in your XAD, using the Advice XAD tag. The usage is really simple, and I do not think you will have troubles on it.
In XAD, to define an external source, do this:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE aspect SYSTEM "../aop.dtd">

<aspect>
    <pointcut ...>
        <advice src="../MyAdviceExternalSource.php" />
        <![CDATA[
            echo "Here!<br />";
        ]]>
        <advice src="../MyAdviceExternalSource2.php" />
        <advice src="../MyAdviceExternalSource3.php" asrequire="true" />
    </pointcut>
</aspect>
NOTE: Since version 1.0 RC 3, it is possible to have two different behaviors of external advice code. This is controlled by asrequire XAD attribute (default value is false), and does this: The tendency of this package is to move to default behavior as a require (asrequire="true"), since it optimizes A LOT of the necessary compiler time.

By doing this, you will load the file "MyAdviceExternalSource.php", that MUST have the <?php and ?> tags to enclosure PHP code.
This works exactly like any other PHP script, that you can close the PHP tag, print some HTML and then turn back to PHP. Just remember that PHP code must contains the PHP tags.
The Pointcut instance will, then, contains the merge of all defined Advices (CDATAs and Advices). To retrieve the whole merged code, you can access this: $advice = & $pointcut->getAdvice();
You will experience that $advice variable will contain an instance of Advice class.

4.2.3. Applying restrictions

Restriction attributes will filter the occurency of your Advice in compiled code. This is obvious, but there are some restrictions that must be defined.
These filters enable you to define the Advice exactly in a Join Point or Pointcut. Read the attributes carefully, they have a lot of meaning in the way of package works.

auto="begin|after|around"

This is optional, but if not set, the attribute "name" must be defined.
If this attribute is included, this exposes which AutoPointcut will have the following Advice code. Since version 1.0 RC 1, it is possible to define one of the two possibilities, and version 1.0 RC 3 implements another one:

NOTE: Since version 1.0 RC 3, it is possible to use "around" AutoPointcut. Altho this is a great utility, you have to be careful about how to use it. You can use it without any problems, but there are some cases that you MUST pay attention: when you are using levels. What does this means?
A level is when you have some nested block inside, like an if statement, while statement, try-catch, etc.
I will highlight one example:
function getLine() {
    if ($this->line < 0) {
    	return 0;
    } // end of if statement
	
    return $this->line;
} // end of method
A simple code, but can cause some headache, specially if I want to apply this Advice:
<![CDATA[
    try {
        proceed();
    } catch ( Exception $e ) {
        die( $e->getMessage() );
    }
]]>
When I compile, It will result in this compiled file (I added identation to show you the problem):
        function getLine() {
            /* AOP "before" Auto Code */
            try {
                if ($this->line < 0) {

                /* AOP "after" Auto Code */
                } catch ( Exception $e ) {
                    die( $e->getMessage() );
                }

                return 0;
            } // end of if statement
        } catch ( Exception $e ) {
            die( $e->getMessage() );
        }

    /* AOP "after" Auto Code */
    } catch ( Exception $e ) {
        die( $e->getMessage() );
    }

    return $this->line;
} // end of method
As you can see, the last curly brace is two levels out of scope. Then the compiles file will generate successfully, but when loaded, it will report a fatal error.

My recommendation is to do not use levels inside an "around" AutoPointcut or do not use more than a single return statement in the method declaration. PLEASE, PAY ATTENTION ON THIS PART!
I still need to plan in a solution to it. Currently, the only I can see is a internal complete reestructure of the compiler. Maybe a true compiler implementation, a PHP AST Compiler. =\
name="...[, ...]"

This is optional, but if not set, the attribute "auto" must be defined.
If this attribute is included, this exposes which CustomPointcut will have the following Advice code.

NOTE: Since version 1.0 RC2, it is possible to define more than one join point for each Pointcut. All you have to do is to separate the name with comma, i.e., if you want to define a Pointcut to be applied in MyJoinPoint1 and MyJoinPoint2, just set the name as this: <pointcut name="MyJoinPoint1, MyJoinPoint2" ...>...</pointcut>
This new feature can be applied to all properties of Pointcut XAD tag.
function="...[, ...]"

Optional attribute. By defining it, it restricts the Pointcut to that function. If the compiler code is not inside the defined function, it is impossible to retrieve Advice code.
Since Release Candidate 2, it is possible to implement a multiple Pointcut Advice code. Like an array, you define the same Advice to more than one function. Read the note box above.

class="...[, ...]"

Optional attribute, but if defined, it restricts the Pointcut to that class.
The implementation of multiple Pointcut Advice code is allowed in this attribute.

nfunction="...[, ...]"

Optional attribute. By defining it, it restricts the Pointcut to other function, but not the defined. If the compiler code is inside the defined function, it is impossible to retrieve Advice code.
This restriction was added in Release Candidate 3, and can deal with array definitions.

nclass="...[, ...]"

Optional attribute, but if defined, it restricts the Pointcut to all classes, except the listed ones.
This restriction was added in Release Candidate 3.
The implementation of multiple Pointcut Advice code is allowed in this attribute too.

4.3. PHP Class Code

4.3.1. Custom Pointcuts

The original release of Transparent PHP AOP covered just custom pointcuts. This is the basic - but powerful - functionality of this package, that solves all your wishes while talking about include special behaviors in your class code.
A Custom Pointcut, usually written in a single word, is a Join Point (AOP theory) that enables you to define points that XAD can incorporate custom Advice code. XAD must define the "name" pointuct attribute in order to include special Advice code in the CustomPointcut.

A Custom Pointcut is defined using a PHP special comment, like this: /// Pointcut: XXX
Changing XXX to your pointcut desirable name, you have a Join Point defined. The following 2 codes describe a PHP Class and a XAD:

<?php

class Test {
    ...

    function someMethod($arg1, $arg2) {
        // Some stuff here
        ...
		
        /// Pointcut: simpleCustomPointcut
        ...
    }

    ...
}

?>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE aspect SYSTEM "../aop.dtd">

<aspect>
    <pointcut name="simpleCustomPointcut" class="Test">
    <![CDATA[
        echo "Here!<br />";
    ]]>
    </pointcut>
</aspect>

4.3.2. Automatic Pointcuts

This is the cute little baby of this package.
An Automatic Pointcut, usually called as AutoPointcut, is a Pointcut that strictly follows AOP theory. You do not need to define a PHP comment in your class code. All you have to do is to define the Advice code in the XAD file. To be applied in an AutoPointcut, you must have to use "auto" attribute of pointcut XML node. The "Quick Tutorial" section exposes exactly how to use this feature. Please move to there and take a look at XAD file.

4.4. Application Loading

4.4.1. Loading Class File

Simple as take a lolipop from a child. This is how I describe the expertise needed to compile and load the class file using AOP approach.
Currently, you have your class inclusion using probably this: require_once "class.MyObject.php";
To incorporate the AOSD, you simply have to change this command to: require_aop("class.MyObject.php", "myXAD.xml");

I will explain in detail. the require_aop function takes 2 arguments:

The second argument accepts a wide range of possibilities: As you can see, it is possible to use directories as a Weave. This will track for last modified date of the directory, and will recompile the package if necessary. A Lazy Load Pattern is implemented internally, to prevent looping though directory's content before the right time.
Aspects are loaded from Unique instances (Singleton), to prevent memory leak. Also, a Registry Pattern is implemented internally.

So, I want to incoporate the "myXAD.xml" Aspect Definition file into my Original Class file "class.MyObject.php". First you have to load the require_aop function (that includes the whole AOP system), by loading the "func.require_aop.php" file.
After that, you can load your class via require_aop function, something like this:

require_aop("class.MyObject.php", "myXAD.xml");

The whole example can be found in "Quick Tutorial" section, described in the beginning of this manual.

4.4.2. Modifying Compile Options

People usually ask my about the Compiler Options. I have to tell you that you do not need to modify Compiler Options, as soon as you are really sure of what are you doing. I enabled the Compiler Options just to simplify programmers life, but they maybe not recommended for production usage.

AOP::CACHE("...");

Default value: Original Class file directory. To reset its value, use AOP::CACHE(".");
If you define another directory to AOP using this property, all the compiled class codes will be created there. This is very useful if you do not want to mantain all your folders with permissions to read/write. The argument to be passed is a valid directory.
Please remember that this property just configure the compiled files directory, it do not rewrite the current directory. For this, take a look at getcwd and chdir PHP functions.

AOP::COMPACT(true|false);

Default behavior of this property is false.
If defined as "true", the Advice code will not be compacted, and lines reference between original class file and compiled file can differ. This is a very useful tool if you are looking for PHP Advice code error, but it is not the ideal thing to use it in production environment; although it will not overhead your system an will not implicate in load time. It is not recommended just because of the changes in the lines.

AOP::RECOMPILE(true|false);

Default behavior is false.
I really do not know why I added this. Maybe to satisfy "build on-the-fly" fans.
If you define this property as "true", every time your scripts runs, it will recompile the AOP compiled file, even if both files (XAD and Original Class) have not been changed.

NOTE: Do not use this in production environment.