Created
June 23, 2014 09:05
-
-
Save jamesBan/d8dd1a41d3dd8adc75fc to your computer and use it in GitHub Desktop.
php 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 | |
| /** | |
| * Aspect | |
| * @source http://www.jaceju.net/blog/archives/327/ | |
| * | |
| */ | |
| class Aspect | |
| { | |
| /** | |
| * Name of target class | |
| * | |
| * @var string | |
| */ | |
| private $_className = null; | |
| /** | |
| * Target object | |
| * | |
| * @var object | |
| */ | |
| private $_target = null; | |
| /** | |
| * Event callback | |
| * | |
| * @var array | |
| */ | |
| private $_eventCallbacks = array(); | |
| /** | |
| * Add object | |
| * | |
| * @param object $target | |
| * @return Aspect | |
| */ | |
| public static function addObject($target) | |
| { | |
| return new Aspect($target); | |
| } | |
| /** | |
| * Contructor | |
| * | |
| * @param object $target | |
| */ | |
| public function __construct($target) | |
| { | |
| if (is_object($target)) { | |
| $this->_target = $target; | |
| $this->_className = get_class($this->_target); | |
| } | |
| } | |
| /** | |
| * Register event | |
| * | |
| * @param string $eventName | |
| * @param string $methodName | |
| * @param callback $callback | |
| */ | |
| private function _registerEvent($eventName, $methodName, $callback, $args) | |
| { | |
| if (!isset($this->_eventCallbacks[$methodName])) { | |
| $this->_eventCallbacks[$methodName] = array(); | |
| } | |
| if (!is_callable(array($this->_target, $methodName))) { | |
| throw new Exception(get_class($this->_target) . '::' . $methodName . ' is not exists.'); | |
| } | |
| if (is_callable($callback)) { | |
| $this->_eventCallbacks[$methodName][$eventName] = array($callback, $args); | |
| } else { | |
| $callbackName = Aspect::getCallbackName($callback); | |
| throw new Exception($callbackName . ' is not callable.'); | |
| } | |
| } | |
| /** | |
| * Register 'before' handler | |
| * | |
| * @param string $methodName | |
| * @param callback $callback | |
| */ | |
| public function before($methodName, $callback, $args = array()) | |
| { | |
| $this->_registerEvent('before', $methodName, $callback, (array) $args); | |
| } | |
| /** | |
| * Register 'after' handler | |
| * | |
| * @param string $methodName | |
| * @param callback $callback | |
| */ | |
| public function after($methodName, $callback, $args = array()) | |
| { | |
| $this->_registerEvent('after', $methodName, $callback, (array) $args); | |
| } | |
| /** | |
| * Register 'on catch exception' handler | |
| * | |
| * @param string $methodName | |
| * @param callback $callback | |
| */ | |
| public function onCatchException($methodName, $callback, $args = array()) | |
| { | |
| $this->_registerEvent('onCatchException', $methodName, $callback, (array) $args); | |
| } | |
| /** | |
| * Trigger event | |
| * | |
| * @param string $eventName | |
| */ | |
| private function _trigger($eventName, $methodName, $target) | |
| { | |
| if (isset($this->_eventCallbacks[$methodName][$eventName])) { | |
| list($callback, $args) = $this->_eventCallbacks[$methodName][$eventName]; | |
| $args[] = $target; | |
| call_user_func_array($callback, $args); | |
| } | |
| } | |
| /** | |
| * Execute method | |
| * | |
| * @param string $methodName | |
| * @param array $args | |
| * @return mixed | |
| */ | |
| public function __call($methodName, $args) | |
| { | |
| if (is_callable(array($this->_target, $methodName))) { | |
| try { | |
| $this->_trigger('before', $methodName, $this->_target); | |
| $result = call_user_func_array(array($this->_target, $methodName), $args); | |
| $this->_trigger('after', $methodName, $this->_target); | |
| return $result ? $result : null; | |
| } catch (Exception $e) { | |
| $this->_trigger('onCatchException', $methodName, $e); | |
| throw $e; | |
| } | |
| } else { | |
| throw new Exception("Call to undefined method {$this->_className}::$methodName."); | |
| } | |
| } | |
| /** | |
| * Get name of callback | |
| * | |
| * @param callback $callback | |
| * @return string | |
| */ | |
| public static function getCallbackName($callback) | |
| { | |
| $className = ''; | |
| $methodName = ''; | |
| if (is_array($callback) && 2 == count($callback)) { | |
| if (is_object($callback[0])) { | |
| $className = get_class($callback[0]); | |
| } else { | |
| $className = (string) $callback[0]; | |
| } | |
| $methodName = (string) $callback[1]; | |
| } elseif (is_string($callback)) { | |
| $methodName = $callback; | |
| } | |
| return $className . (($className) ? '::' : '') . $methodName; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment