Aspect-oriented Programming in PHP

WARNING: This article features ANCIENT code! I'm keeping it online because it's interesting to see what I was thinking 10+ years ago. But you DEFINITELY should not be using this code. Anything you're reading about on this page has changed significantly since this was written.

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

It's an Aspect-Oriented Programming module for PHP that gives you some rather cool meta-programming opportunities, installable thru PECL, or if you feel more sporting, by hand.

Immediately interesting to me was the ability to add advice before a method invocation and gain access to all the 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?" (that can turn out to be a frighteningly difficult question in a large, GUI-driven, legacy system)

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());
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.

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 and that sort of thing, but the options are still fairly limited for an existing codebase. So this extension is a breath of fresh air. Logging is simple example, but there are plenty of other interesting uses for this sort of functionality too - user authorization comes to mind as a big one.

It's a pretty neat little project and it's even well documented! Definitely looking forward to getting some more time to play with it.