xtompie/aop

0.2 2023-02-05 10:43 UTC

This package is auto-updated.

Last update: 2025-04-06 01:45:59 UTC


README

This library require changes in the original source code.

In simplified and generalized term AOP is Publish/Subscribe system with Middlewares.

Requiments

PHP >= 8.0

Installation

Using composer

composer require xtompie/aop

Docs

1. Creating Aspect

Aspect is a class implementing Aspect interface.

<?php

namespace Xtompie\Aop;

interface Aspect
{
    public function order(): float;
    public function joinpoint(string $joinpoint): bool;
    public function advice(Invocation $invocation): mixed;
}

Library provides abstract class GenericAspect.

<?php

use Xtompie\Aop\GenericAspect;

class DebugAspect implements GenericAspect
{
    protected function pointcuts(): array
    {
        return [
            'FoobarService::*',
        ];
    }

    public function advice(Invocation $invocation): mixed
    {
        $result = $invocation();
        var_dump([
            'AOP',
            'joinpoint' => $invocation->joinpoint(),
            'args' => $invocation->args(),
            'result' => $result,
        ]);
        return $result;
    }
}

Pointcut is a pattern that can match Joinpoint. Pointcut can have a * character that describes any character in any number of occurrences. If Pointcut dont have * it is equal to Joinpoint.

There is only one type of Advice - around. Before and after can be achive manualy or using GenericAspect.

2. Create AOP system

<?php

use Xtompie\Aop\Aop;

$aop = new Aop([
    new DebugAspect(),
]);

function aop(string $joinpoint, array $args, callable $main): mixed
{
    return $GLOBALS['aop']->__invoke($joinpoint, $args, $main);
}

3. Create joinpoint in service

<?php

class FoobarService
{
    public function baz(int $a): int
    {
        return aop(__METHOD__, func_get_args(), function(int $a) { // <-- added line
            return $a + 1;
        }); // <-- added line
    }
}

4. Changing invocation arguments

<?php

use Xtompie\Aop\GenericAspect;

class AddFiveAspect implements GenericAspect
{
    protected function pointcuts(): array
    {
        return [
            'FoobarService::__invoke',
        ];
    }

    public function advice(Invocation $invocation): mixed
    {
        $invocation = $invocation->withArgs([$invocation->args()[0] + 5]);
        return $invocation();
    }
}

5. Changing aspect orders

The higher the order, the closer it is to the main invocation.

<?php

use Xtompie\Aop\GenericAspect;

class AddFiveAspect implements GenericAspect
{
    public function order(): float
    {
        return 10;
    }

    // ...
}

6. Replace orginal invocation

Dont call invocation chain $invocation().

<?php

use Xtompie\Aop\GenericAspect;

class MinusTeenAspect implements GenericAspect
{
    public function order(): float
    {
        return 999;
    }

    protected function pointcuts(): array
    {
        return [
            'FoobarService::__invoke',
        ];
    }

    public function advice(Invocation $invocation): mixed
    {
        return $invocation->args()[0] - 10;
    }
}