Aspect Oriented Programming in PHP

(2014)

A very frustrating thing in the legacy system at work is that error logging is badly busted. The system is fragile and can't suffer significant downtime, and it would be risky to apply any dramatic fixes. I found a pretty cool PHP module that offers a partial solution:

https://github.com/AOP-PHP/AOP

It's an Aspect-Oriented Programming module for PHP that provides some neat meta-programming opportunities that can be installed though PECL or by hand.

Immediately interesting to me was the ability to add Advice before a method invocation and gain access to all its arguments. For my purposes, this gives a chance to provide system-wide logging/tracing without having to make risky edits to hundreds of files. It also makes it possible to answer the question "under what circumstances does this code get called?". In a large legacy system with a lot of nooks and crannies, that can be a surprisingly difficult question to answer.

As a brief example, it works something like this (added at the beginning of the code):

function myAdvice(AopJoinPoint $jp) {
    $fn = $jp->getFunctionName();
    $args = join(',', $jp->getArguments());
    error_log("$fn($args)");
}
aop_add_before('*()', 'myAdvice');

In the example above, myAdvice() will be run at the beginning of each method or function call (including PHP's built-in functions). Matching everything is overly blunt, but sophisticated matching is possible as well. In most cases, it's easier to just match everything and then ignore the stuff you don't care about.

Despite my general liking of PHP, it does suffer some shortcomings and weak meta-programming is one of them. There's certainly some fun dynamic stuff you can do with call_user_func() and variable arity functions, but the options are still fairly limited for an existing codebase. So this extension is pretty exciting. Logging is simple example, but other uses cases might include things like user authorization.