phpzend-frameworkparameter-passingcollision

zend: parameter collision


I wonder why no one ever asked this question.

Every zend Action function in controller class has 3 paramters, namely 'module', 'controller', and 'action'.

What happens, when I get a parameter named 'action' from a form or url, for example "?action=edit" ??

I tested it: action holds its value from router, not 'edit'.

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

How could I pass the parameter named "action", if I had to ??

Thanks in advance.


Solution

  • The default route is Zend_Controller_Router_Route_Module which uses default keys for module, controller, & action:

    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;
    }
    

    You can see that the default module route has default keys for mvc params, however, it will use the keys set by the request object if it exists and we can modify these keys.

    e.g. in your bootstrap:

    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);
        }
    }
    

    Now you can use module, controller, & action as $_GET params.