Skip to content

Instantly share code, notes, and snippets.

@afaur
Forked from bayleedev/aop.php
Last active June 7, 2017 18:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save afaur/3abf419a876c170560c1e0b16a6d179e to your computer and use it in GitHub Desktop.
Save afaur/3abf419a876c170560c1e0b16a6d179e to your computer and use it in GitHub Desktop.
aspect oriented programming with traits in php
<?php
/**
* AOP Trait
* Used to created aop for your class.
*/
trait AOP {
public $filters = [];
public function applyFilter($NF) {
list($fnName, $fn) = $NF;
($this->unlessFilter($fnName)) && $this->initFilter($fnName);
return $this->filters[$fnName][] = $fn;
}
private function unlessFilter($fnName) { return (empty($this->filters[$fnName])); }
private function initFilter($fnName) { $this->filters[$fnName] = []; }
public function _filter($FPC) { return $this->callQueue($FPC); }
private function callQueue($FPC) {
list($fnName, $fnParams, $fnCallback) = $FPC;
$queue = new AOPChain($this, $this->newChain($fnName, $fnCallback));
return $queue->first($fnParams);
}
private function newChain($fnName, $fnCallback) {
$filterCallbacks = $this->callbacks($fnName);
$filterCallbacks[] = $fnCallback;
return $filterCallbacks;
}
private function callbacks($fnName) { return $this->filters[$fnName]; }
}
/**
* Responsible for creating the chain queue and processing it
*/
class AOPChain {
public $host = null;
public $callbacks = [];
public function __construct($host, $callbacks) {
$this->host = $host;
$this->callbacks = $callbacks;
$this->position = 0;
}
// Helps with the first item in the chain by prepending known variables
public function first($params) { return $this->next([$this->host, $params, $this]); }
// Called inside of a filter `$chain->next($self, $params, $chain);`
public function next($SPC) { return call_user_func($this->callbacks[$this->position++], $SPC); }
}
class Person {
use AOP;
public function address($name, $location) {
$fnName = __FUNCTION__;
$params = compact('name', 'location');
$callback = function($SPC) {
list($self, $params, $chain) = $SPC;
extract($params);
echo 'Hello: '. $name .' Your location is: '. $location;
};
return $this->_filter([$fnName, $params, $callback]);
}
}
$foo = new Person();
$callback = function($SPC) {
list($self, $params, $chain) = $SPC;
try {
$data = $chain->next([$self, $params, $chain]);
} catch (Exception $e) {
echo 'you caught something';
}
};
$foo->applyFilter(['address', $callback]);
echo $foo->address('blaine', 'tulsa');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment