【问题标题】:zend: parameter collisionzend:参数冲突
【发布时间】:2012-08-27 06:34:05
【问题描述】:

我想知道为什么从来没有人问过这个问题。

控制器类中的每个zend Action函数都有3个参数,分别是'module'、'controller'和'action'。

当我从表单或 url 获取名为“action”的参数时会发生什么,例如“?action=edit”??

我对其进行了测试:动作的价值来自路由器,而不是“编辑”。

public function someAction() {
    $params = $this->getRequest()->getParams();
...

如果必须要传递名为“action”的参数,我该如何传递??

提前致谢。

【问题讨论】:

    标签: zend-framework parameter-passing collision


    【解决方案1】:

    默认路由是Zend_Controller_Router_Route_Module,它使用模块、控制器和操作的默认键:

    protected $_moduleKey     = 'module';
    protected $_controllerKey = 'controller';
    protected $_actionKey     = 'action';
    
    // ...
    
    /**
     * Set request keys based on values in request object
     *
     * @return void
     */
    protected function _setRequestKeys()
    {
        if (null !== $this->_request) {
            $this->_moduleKey     = $this->_request->getModuleKey();
            $this->_controllerKey = $this->_request->getControllerKey();
            $this->_actionKey     = $this->_request->getActionKey();
        }
    
        if (null !== $this->_dispatcher) {
            $this->_defaults += array(
                $this->_controllerKey => $this->_dispatcher->getDefaultControllerName(),
                $this->_actionKey     => $this->_dispatcher->getDefaultAction(),
                $this->_moduleKey     => $this->_dispatcher->getDefaultModule()
            );
        }
    
        $this->_keysSet = true;
    }
    
    /**
     * Matches a user submitted path. Assigns and returns an array of variables
     * on a successful match.
     *
     * If a request object is registered, it uses its setModuleName(),
     * setControllerName(), and setActionName() accessors to set those values.
     * Always returns the values as an array.
     *
     * @param string $path Path used to match against this routing map
     * @return array An array of assigned values or a false on a mismatch
     */
    public function match($path, $partial = false)
    {
        $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;
            }
    
            if (count($path) && !empty($path[0])) {
                $values[$this->_controllerKey] = array_shift($path);
            }
    
            if (count($path) && !empty($path[0])) {
                $values[$this->_actionKey] = array_shift($path);
            }
    
            if ($numSegs = count($path)) {
                for ($i = 0; $i < $numSegs; $i = $i + 2) {
                    $key = urldecode($path[$i]);
                    $val = isset($path[$i + 1]) ? urldecode($path[$i + 1]) : null;
                    $params[$key] = (isset($params[$key]) ? (array_merge((array) $params[$key], array($val))): $val);
                }
            }
        }
    
        if ($partial) {
            $this->setMatchedPath($matchedPath);
        }
    
        $this->_values = $values + $params;
    
        return $this->_values + $this->_defaults;
    }
    

    你可以看到默认模块路由有默认的mvc参数键,但是,如果存在,它会使用请求对象设置的键,我们可以修改这些键。

    例如在您的引导程序中:

    class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
    {
        protected function _initRequestKeys()
        {
            $this->bootstrap('frontcontroller');
            $frontController = $this->getResource('frontcontroller');
            /* @var $frontController Zend_Controller_Front */
    
            $request = new Zend_Controller_Request_Http();
    
            // change action key
            $request->setActionKey("new_action_key");
    
            // change module
            $request->setModuleKey("new_module_key");
    
            // change controller
            $request->setControllerKey("new_controller_key");
    
    
            // don't forget to set the configured request
            // object to the front controller
            $frontController->setRequest($request);
        }
    }
    

    现在您可以使用 modulecontrolleraction 作为 $_GET 参数。

    【讨论】:

      【解决方案2】:

      经过一些测试,您如何传递关键 "action" 似乎很重要。

      如果您尝试使用 $this-&gt;_request-&gt;getParams() 传递名为 "action" 的参数,您将获得控制器操作值键对。

      如果您从带有$form-&gt;getValues() 的表单中传递 "action" 键,您将从名为 "action" 的表单元素中检索值。

      与许多事情一样,您的用例决定了您需要如何处理这种情况。

      祝你好运。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-26
        • 2020-07-01
        • 2014-11-21
        相关资源
        最近更新 更多