<?PHP
/*
When we are developing big complex projects Object-Oriented programming paradigm isn't able
to provide a clear structure of business logic components. Aspect-Oriented Programming
allows to separate business logic and through functionality (logging, caching, transaction control, etc).
AOP Library for PHP extends basic PHP capabilities using Aspect-Oriented constructions. You
can learn more about Aspect-Oriented Programming at http://en.wikipedia.org/wiki/Aspect-oriented_programming
*/
include("aop.lib.php");
$aspect1 = new Aspect();
$pc1 = $aspect1->pointcut("call Sample::Sample or call Sample::Sample2");
$pc1->_before("print 'PreProcess<br />';");
$pc1->_after("print 'PostProcess<br />';");
$pc1->destroy();
Class Sample {
var $aspect;
function Sample($aspect1) {
$this->aspect = &$aspect1;
Advice::_before($this->aspect);
print 'Some business logic of Sample<br />';
Advice::_after($this->aspect);
}
function Sample2() {
Advice::_before($this->aspect);
print 'Some business logic of Sample2<br />';
Advice::_after($this->aspect);
}
}
$Sample = new Sample(&$aspect1);
$Sample->Sample2();
?>
/**
* Aspect class, which declare an aspect
* @package Aspect-Oriented Programming Library
* @author $Author: sheiko $
*/
class Aspect {
var $pointcuts;
/**
* Class constructor
* @return object
*/
function Aspect() {
$this->pointcuts = array("AAA");
return $this;
}
/**
* Add set of join points
* @param string $CommandString special string in format "call MethodName1 or call MethodName2"
* @return boolean
*/
function pointcut($CommandString) {
return new Pointcut($CommandString, &$this->pointcuts);
}
/**
* Class destructor
* @return boolean
*/
function destroy() {
unset($this);
}
}
/**
* Pointcut class, which declare an pointcut of the aspect (http://en.wikipedia.org/wiki/Advice_in_aspect-oriented_programming)
* @package Aspect-Oriented Programming Library
* @author $Author: sheiko $
*/
class Pointcut extends Aspect {
var $Methods;
var $pointcuts;
/**
* Class constructor
* @return object
*/
function Pointcut($CommandString, $pointcutsReference) {
$this->Methods = array();
$this->pointcuts = &$pointcutsReference;
// Validate Input Parameters
if(!is_string($CommandString)) trigger_error("CommandString parameter must be STRING", E_USER_ERROR);
function __apply($Point, $EvalCode) {
$Method = '';
// Validate Input Parameters
if(!$EvalCode) trigger_error("This function parameter is invalid. Value of the parameter has to satisfy the eval code syntax", E_USER_ERROR);
if(!$this->Methods) trigger_error("There is a need to define pointcut", E_USER_ERROR);
foreach($this->Methods as $Method) {
$this->pointcuts[$Method][$Point] = $EvalCode;
}
return true;
}
/**
* Class destructor
* @return boolean
*/
function destroy() {
unset($this);
}
}
/**
* Advice service function package (http://en.wikipedia.org/wiki/Advice_in_aspect-oriented_programming)
* @package Aspect-Oriented Programming Library
* @author $Author: sheiko $
*/
class Advice {
/**
* Parent method name getting
* @return boolean
*/
function getMethodName() {
$backtrace = debug_backtrace();
return $backtrace[2]["class"]."::".$backtrace[2]["function"];
}
/**
* _Before process declaration
* @param object $AspectObj
* @return boolean
*/
function _before($AspectObj) {
$MethodName = '';
if (gettype($AspectObj)!="object") trigger_error("This function parameter is invalid. Value of the parameter has to satisfy the Aspect object requirements", E_USER_ERROR);
if($AspectObj->pointcuts [Advice::getMethodName()]["_before"]) {
$Result = @eval($AspectObj->pointcuts [Advice::getMethodName()]["_before"]." return true;" );
if(!$Result) _trigger::error("_before process of the applied Aspect contains incorrect eval code");
}
return true;
}
/**
* _After process declaration
* @param object $AspectObj
* @return boolean
*/
function _after($AspectObj) {
$MethodName = '';
if (gettype($AspectObj)!="object") trigger_error("This function parameter is invalid. Value of the parameter has to satisfy the Aspect object requirements", E_USER_ERROR);
if($AspectObj->pointcuts [Advice::getMethodName()]["_after"]) {
$Result = @eval($AspectObj->pointcuts [Advice::getMethodName()]["_after"]." return true;" );
if(!$Result) _trigger::error("_after process of the applied Aspect contains incorrect eval code");
}
return true;
}
}
/**
* Trigger service function package
* @package Aspect-Oriented Programming Library
* @author $Author: sheiko $
*/
class _trigger {
/**
* Error trigger
* @param string $ErrorMessage
* @return boolean
*/
function error($ErrorMessage) {
$backtrace = debug_backtrace();
$index = 2;
die("<b>AOP Error:</b> ".$ErrorMessage." in <b>".$backtrace[$index]["file"]."</b> on line <b>".$backtrace[$index]["line"]."</b>");
return true;
}
}
?>