Friday, June 24, 2011

Aspect Oriented PHP

I'd heard about aspect-oriented programming a couple years ago and always thought it was a great idea, but never had the time/motiviation to learn a whole new language and environment to do it.  Besides, aspect-oriented isn't mainstream enough (yet) to be well-supported.

Fast forward to working on a PHP application with plenty of cross-cutting concerns - logging, database management, etc., and a few google searches latter, I saw plenty of folks have tried to implement aspect-oriented PHP libraries on their own.  Some are compiled, some use other languages/frameworks to do the dirty work and provide syntactic sugar.  My favorite write up came from here.  Simple enough to understand, and simple enough to even get my own attempt working.  Here's the raw code in all its untested and unmodified first-draft form (and try http://codepad.org/PaL8PRce to see it actually work):





class LogAspect
{
public $object;
public $advice;
public function __construct($obj)
{
$this->object = $obj;
$this->advice = array();
}


public function weave($when, $method, $advice)
{
$this->advice[$method][$when][] = $advice;
}


public function __call($name, $args)
{
foreach($this->advice[$name]["BEFORE"] as $advice)
{
  call_user_func(array($this,$advice));
}
call_user_func(array(&$this->object,$name),$args);
foreach($this->advice[$name]["AFTER"] as $advice)
{
  call_user_func(array($this,$advice));
}
}


public function Log()
{
echo "Log it!\n";
}
public function LogAgain()
{
echo "Log it again!\n";
}
}


class Foo
{
public function __construct()
{


}
public function doA()
{
echo "DoA!\n";
}
public function doB()
{
echo "DoB!\n";
}
}


$foo = new Foo();
$foo->doA();
$foo->doB();


$fooAspected = new LogAspect($foo);
$fooAspected->weave("BEFORE","doA", "Log");
$fooAspected->weave("AFTER","doA","Log");
$fooAspected->doA();
?>


The output is:



1
2
3
4
5
DoA!
DoB!
Log it!
DoA!
Log it!


I was surprised that it worked as intended!  Now I'll have to do plenty to it to support multiple advices, etc.  But proof of concept!

Related Posts by Categories



0 comments:

Post a Comment