Created
December 14, 2011 10:41
-
-
Save commuterjoy/1476082 to your computer and use it in GitHub Desktop.
PHP 5.4 traits to emulate AOP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// There's a few nasty AOP implementations in PHP that either | |
// rely on code generation or reflection. PHP 5.4 should allow us | |
// to define the horizontal concerns using _traits_ | |
// - ref. http://php.net/manual/en/language.oop5.traits.php | |
/** | |
* A class that does something. Nice, clean. Just business logic. | |
**/ | |
abstract class Base { | |
public function sayHello($arg) { | |
echo "Base class says _hello_ with argument: '$arg' \n"; | |
return true; | |
} | |
public function sayByeBye() { | |
echo "Base class says _bye_bye_ \n"; | |
return true; | |
} | |
} | |
/** | |
* Some logging advice | |
**/ | |
trait LoggerAdvice { | |
// match the signature of the base method and add logging around the sayHello method | |
public function sayHello($arg) | |
{ | |
echo 'logging before ' . get_class($this) . "\n"; | |
$r = parent::sayHello($arg); | |
// eg, could add logging conditionally on the return value | |
echo 'logging after - return value of ' . $r . "\n"; | |
echo $this->log(); | |
} | |
public function sayByeBye() { | |
parent::sayByeBye(); | |
echo $this->log(); | |
} | |
// provide common logging across methods | |
protected function log() | |
{ | |
echo "****log\n"; | |
} | |
} | |
/** | |
* Apply the advice to an concrete instance of the class | |
**/ | |
class MyHelloWorld extends Base { | |
use LoggerAdvice; | |
} | |
// call the method with it's advice | |
$o = new MyHelloWorld(); | |
$o->sayHello('foo'); | |
$o->sayByeBye(); | |
?> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
That's interesting, but I still have several technical doubts on best practices for performing AOP with Traits:
use
ing class)use
ing the trait? How to communicate minimal requirements to the developer that wants to use the trait?__construct
magic method, calling theparent::construct()
and then theinitialize()
method?use
ing class; that is of course unrealistic and inflexibleuse
ing class?