Skip to content
Matthias Molitor edited this page Mar 25, 2012 · 8 revisions

Aspect Proposal

Aspect Declaration

Aspects are represented by plain old PHP classes and may contain an arbitrary number of pointcuts and advices.

Pointcuts are provided by public methods of the aspect:

public function pointcutAll()
{
    return new AspectPHP_Pointcut_All();
}

Advices are represented by public methods that (optionally) accept joinpoints:

public function logCall(AspectPHP_JoinPoint $joinPoint)
{
    echo $joinPoint->getMethod() . ' called.' . PHP_EOL;
}

Pointcuts are connected to advices via annotations. The annotations are assigned to the advice methods. The advice type is used as doc tag (for example @before or @after). The name of the method that provides the pointcut is used as value. Each tag may be used several times.

/**
 * @before pointcutAll()
 * @after pointcutLogClasses()
 * @after pointcutSaveModel()
 */
public function logCall(AspectPHP_JoinPoint $joinPoint)
{
    // [...]
}

The interface AspectPHP_Aspect is used to tag aspects. The interface does not require any methods as there is no type of method that is needed by all aspects. Using an interface is for aspects gives the possibility of type hinting.

Aspect Registration

An instance of AspectPHP_Manager is used to register aspects. The manager can be retrieved at initialization time:

// Initialize the AspectPHP environment.
$environment = new AspectPHP_Environment();
$environment->initialize();

$manager = $environment->getManager();
$manager->register(new MyDemoAspect());

Aspect registration is required, otherwise its advices will not be invoked.

The manager detects available advices and converts them to AspectPHP_Advice objects:

interface AspectPHP_Advice
{
    /**
     * @return AspectPHP_Pointcut
     */
    public function getPointcut();
    
    /**
     * @param AspectPHP_JoinPoint $joinPoint
     */
    public function invoke(AspectPHP_JoinPoint $joinPoint);
}

An advice object encapsulates an advice callback and its corresponding pointcut. It is used to invoke the advice code.

Advice Invocation

The manager uses the pointcuts to determine advices that should be invoked when a specific method is executed.

A list all advices for a method can be retrieved via getAdvicesFor():

$manager->getAdvicesFor('Demo::method');

The method returns an instance of AspectPHP_Advice_Container that provides access to the different types of registered advices:

interface AspectPHP_Advice_Container
{
    /**
     * @return AspectPHP_Advice_Composite
     */
    public function before();
    
    /**
     * @return AspectPHP_Advice_Composite
     */
    public function afterReturning();
    
    /**
     * @return AspectPHP_Advice_Composite
     */
    public function afterThrowing();
    
    /**
     * @return AspectPHP_Advice_Composite
     */
    public function after();
}

The advices for each type are contained in an AspectPHP_Advice_Composite object:

interface AspectPHP_Advice_Composite extends AspectPHP_Advice, Countable
{
    public function add(AspectPHP_Advice $advice);
}

The code template that is injected into compiled classes (AspectPHP_Transformation_JoinPoints::_aspectPHPInternalHandleCall) is responsible for handling the invocation of the different advice types.

Clone this wiki locally