From the previous article we probably know the definition of the filter and how to configure, this section says the implementation process
Public function run ($handlerAdapter = null) {$handlerAdapter!== null && $this->handleradapter = $handlerAdapt er; $module = $this->getmodules (); $handlerPath = $module [' Controller-path ']. ‘.‘ . Ucfirst ($this->handleradapter->getcontroller ()). $module [' Controller-suffix ']; $className = Wind::import ($handlerPath); if (!class_exists ($className)) throw new Windexception (' Your requested \ '. $handlerPath. ' \ ' is not found in this server. ', 404); $handler = new $className (); $handler->setdelayattributes (' errormessage ' = = Array (' ref ' = ' errormessage '), ' forward ' = ' = ' Array (' ref ' = ' forward ')); $handlerAdapter!== null &&A mp $this->resolveactionfilters ($handler); try {$forward = $handler->doaction ($this->handleradapter); $this- >dodispatch ($forward);} catch (Windforwardexception $e) {$this->dodispatch ($e->getforward ()),} catch (Windactionexception $e) {$this- >senderrormessage ($e->geterror () $e->geterror (): $e->getmessaGE ()), $e->getcode ());} catch (Windexception $e) {$this->senderrormessage ($e->getmessage (), $e->getcode ());}}
Note that the Handleadapter attribute, what is this variable in the end?
Let's take a look at the console
Let me explain here that this is an example of windclassproxy, remember how it was created, and then post this code
/** * Parse the configuration information of the action filter chain * * @param windsimplecontroller $handler * @return void */protected function resolveaction Filters (& $handler) {if (! $filters = $this->getconfig (' Filters ')) return;/* @var $cache Abstractwindcache */$_ Filters = Array (), if ($cache = wind::getcomponent (' Windcache ')) {$_filters = $cache->get (' Filters ');} $_token = $this->handleradapter->getmodule (). ‘/‘ . $this->handleradapter->getcontroller (). ‘/‘ . $this->handleradapter->getaction (), if (!isset ($_filters[$_token)) {foreach ($filters as $_filter) {if (Empty ($ _filter[' class ')) Continue;$_pattern = empty ($_filter[' pattern ')? ': $_filter[' pattern '];unset ($_filter[' pattern '); if ($_pattern) {$_pattern = Str_replace (Array (' * ', '/'), Array (' \w * ', ' \ \ '), $_pattern), if (In_array ($_pattern[0], array (' ~ ', '! '))) {$_pattern = substr ($_pattern, 1); if (Preg_match ('/^ '. $_pattern. ' $/i ', $_token)) continue;} else {if (!preg_match ('/^ '. $_pattern. ' $/i ', $_token)) continue;}} $_filters[$_token][] = $_filter;} $cache && $cache->set (' Filters ', $_filters);} if (empty ($_filters[$_token))) return;/* @var $proxy windclassproxy */$proxy = Windfactory::createinstance (Wind:: Import (' WIND:filter.proxy.WindClassProxy ')); $proxy->registertargetobject ($handler); foreach ($_filters[$_ Token] as $value) {$proxy->registereventlistener ($this->factory->createinstance (Wind::import ($value [' Class ']), Array ($handler->getforward (), $handler->geterrormessage (), $this->handleradapter, $value)), ' DoAction ');} $handler = $proxy;}
The point is here.
$proxy = Windfactory::createinstance (Wind::import (' WIND:filter.proxy.WindClassProxy ')); $proxy Registertargetobject ($handler); foreach ($_filters[$_token] as $value) {$proxy->registereventlistener ($this Factory->createinstance (Wind::import ($value [' class ']), Array ($handler->getforward (), $handler- GetErrorMessage (), $this->handleradapter, $value)), ' doAction ');}
Create a proxy class, and then fix an event, instantiate the filter as an event, and wait for it to be triggered, and don't know why.
Well, everything is ready, only owes Dongfeng pull, and see how it works so pull
try {$forward = $handler->doaction ($this->handleradapter); $this->dodispatch ($forward);} catch ( Windforwardexception $e) {$this->dodispatch ($e->getforward ())} catch (Windactionexception $e) {$this Senderrormessage ($e->geterror () $e->geterror (): $e->getmessage ()), $e->getcode ());} catch (Windexception $e) {$this->senderrormessage ($e->getmessage (), $e->getcode ());}
Here will call doaction this method, but this method is not found at Windproxyclass, so will invoke the Magic method of PHP pull, as follows
Public Function __call ($methodName, $args) {$listeners = Isset ($this->_listener[$methodName])? $this->_listener [$methodName]: Array (), if (Empty ($listeners)) return Call_user_func_array (Array ($this->_instance, $methodName), $ args); $interceptorChain = $this->_getinterceptorchain ($methodName); $interceptorChain->addinterceptors ($ listeners); $interceptorChain->setcallback (Array ($this->_getinstance (), $methodName), $args); return Call_ User_func_array (Array ($interceptorChain->gethandler (), ' Handle '), (array) $args);}
Well, the climax comes, first of all to determine whether this method is bound to a bunch of listener, if not, it is directly called to calculate, if any, to join the chain
It's a tricky place to see.
* Interceptor Execution Entry * * @param mixed $var =: The interface accepts arbitrary parameters and will be passed to the interceptor's pre-and post-operation * @return Mixed returns the final result of the Intercept chain execution */public function handle () {$args = Func_get_args (); $this->result = Call_user_func_array (Array ($this, ' Prehandle '), $args); if ($this, Result!== null) {return $this->result;} if (null!== ($handler = $this->interceptorchain->gethandler ())) {$this->result = Call_user_func_array (Array ( $handler, ' handle '), $args); The handle method that executes the filter} else {$this->result = Call_user_func_array (Array ($this->interceptorchain, ' handle '), $args); If the returned handle is empty, then the handle method of the filter chain is executed, namely callback, call Controller}call_user_func_array (Array ($this, ' Posthandle '), $args); return $this->result;}
/** * Returns the next interceptor in the Intercept chain * * @return windhandlerinterceptor */public function GetHandler () {if ($this->_ Interceptors) <= 1) {return $this;} $handler = Next ($this->_interceptors), if ($handler = = = False) {reset ($this->_interceptors); return null;} if (method_exists ($handler, ' handle ')) {$handler->sethandlerinterceptorchain ($this);//What is the use of this setting? Died for the last call to the handle method of the filter chain return $handler;} return $this->gethandler ();}
/** * Execute callback method * * @return Mixed $var =: Returns NULL if callback is not set otherwise returns the result of the callback function * @throws windexception if the callback function call fails Exception */public function handle () {Reset ($this->_interceptors), if ($this->_callback = = = null) return null;if (is_ String ($this->_callback) &&!function_exists ($this->_callback)) {throw new Windexception (' [Filter. Windhandlerinterceptorchain.handle] '. $this->_callback, windexception::error_function_not_exist);} $this->_args | | $this->_args = Func_get_args (), Return Call_user_func_array ($this->_callback, (array) $this->_args);}
This is the last execution, the filter one after the execution, the execution of callback pull, there is time to draw a diagram will be easier to understand pull
Trick Phpwind Filter Execution flow