`

zf 的消息路由学习心得

阅读更多

     Jayson Minard的blueprint for php applications中提到了消息入口Bootstrapping的多种实现方式。在zf中1.7中,一个index.php文件的入口已经更近一步的简化。
     当然也是支持传统的写法的。而在FrontController中,接受的url的进行dispatche,其路由情况如下:

        // Begin dispatch
        try {
            /**
             * Route request to controller/action, if a router is provided
             */

            /**
            * Notify plugins of router startup
            */
            $this->_plugins->routeStartup($this->_request);

            $router->route($this->_request);
           
            /**
            * Notify plugins of router completion
            */
            $this->_plugins->routeShutdown($this->_request);

            /**
             * Notify plugins of dispatch loop startup
             */
            $this->_plugins->dispatchLoopStartup($this->_request);

            /**
             *  Attempt to dispatch the controller/action. If the $this->_request
             *  indicates that it needs to be dispatched, move to the next
             *  action in the request.
             */
            do {
                $this->_request->setDispatched(true);

                /**
                 * Notify plugins of dispatch startup
                 */
                $this->_plugins->preDispatch($this->_request);

                /**
                 * Skip requested action if preDispatch() has reset it
                 */
                if (!$this->_request->isDispatched()) {
                    continue;
                }

                /**
                 * Dispatch request
                 */
                try {
                    $dispatcher->dispatch($this->_request, $this->_response);
                } catch (Exception $e) {
                    if ($this->throwExceptions()) {
                        throw $e;
                    }
                    $this->_response->setException($e);
                }

                /**
                 * Notify plugins of dispatch completion
                 */
                $this->_plugins->postDispatch($this->_request);
            } while (!$this->_request->isDispatched());

    重点代码:

$router->route($this->_request);

    $router为一个Zend_Controller_Router_Rewrite对象,_request为一个Zend_Controller_Request_Http对象,其封装了一个http请求,其中有一个参数_requestUri,该参数为一个请求的uri,其形式上可能为/index/index?parameter=value。该uri形式上有两段,其中一段为pathInfo,一部分为queryInfo。

    在Zend_Controller_Router_Rewrite有代码如下:

            // TODO: Should be an interface method. Hack for 1.0 BC  
            if (!method_exists($route, 'getVersion') || $route->getVersion() == 1) {
                $match = $request->getPathInfo();
            } else {
                $match = $request;
            }
                       
            if ($params = $route->match($match)) {
                $this->_setRequestParams($request, $params);
                $this->_currentRoute = $name;
                break;
            }

    其中$match为PathInfo,即/index/index。$router为一个Zend_Controller_Router_Route_Module对象,对象中函数match返回一个数组 ["controller"]=> string(5) "index" ["action"]=> string(5) "index" ["module"]=> string(7) "default"。match函数部分代码如下:

        $this->_setRequestKeys();

        $values = array();
        $params = array();
        
        if (!$partial) {
            $path = trim($path, self::URI_DELIMITER);
        } else {
            $matchedPath = $path;
        }

        if ($path != '') {
            $path = explode(self::URI_DELIMITER, $path);

            if ($this->_dispatcher && $this->_dispatcher->isValidModule($path[0])) {
                $values[$this->_moduleKey] = array_shift($path);
                $this->_moduleValid = true;
            }

    其中:

self::URI_DELIMITER

    是一个const,定义如下:

const URI_DELIMITER = '/';

   于是返回如上所示数组。Zend_Controller_Router_Rewrite对象中使用了函数_setRequestParams设置module、controlloer和action的名称。

    于是在类Zend_Controller_Front中的_request中已经具备了router的信息条件。

    未完待续。

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics