代码之家  ›  专栏  ›  技术社区  ›  Jeffrey04 George

在Zend Framework中将URL段用作操作方法参数

  •  12
  • Jeffrey04 George  · 技术社区  · 17 年前

    http://www.name.tld/controller_name/method_name/parameter_1/parameter_2/parameter_3 ...
    

    然后读取控制器中的参数,如下所示:

    class MyController 
    {
        public function method_name($param_A, $param_B, $param_C ...)
        {
            // ... code
        }
    }
    

    5 回复  |  直到 10 年前
        1
  •  11
  •   Andrew Taylor    17 年前

    看看Zend_控制器_路由器类:

    http://framework.zend.com/manual/en/zend.controller.router.html

    这将允许您定义一个Zend_控制器_路由器_路由,它以您需要的方式映射到您的URL。

    索引控制器的索引操作具有4个静态参数的示例如下:

    $router = new Zend_Controller_Router_Rewrite();
    
    $router->addRoute(
        'index',
        new Zend_Controller_Router_Route('index/index/:param1/:param2/:param3/:param4', array('controller' => 'index', 'action' => 'index'))
    );
    
    $frontController->setRouter($router);
    

    在定义前端控制器后,这将添加到引导程序中。

    一旦采取行动,您就可以使用:

    $this->_request->getParam('param1');
    

    在action方法中访问值。

    安得烈

        2
  •  6
  •   Community Mohan Dere    9 年前

    更新(2016年4月13日): 下面我的答案中的链接已移动并已修复。但是,为了防止它再次消失——这里有一些替代方案提供了有关该技术的一些深入信息,并将原始文章用作参考资料:


    @ Andrew Taylor this tutorial on Zend DevZone .

        3
  •  4
  •   A J    10 年前

    我已经延长了 Zend_Controller_Action 使用我的控制器类,并进行了以下更改:

    在里面 dispatch($action) 方法替换

    $this->$action();

    具有

    call_user_func_array(array($this,$action), $this->getUrlParametersByPosition());

    并添加了以下方法

    /**
     * Returns array of url parts after controller and action
     */
    protected function getUrlParametersByPosition()
    {
        $request = $this->getRequest();
        $path = $request->getPathInfo();
        $path = explode('/', trim($path, '/'));
        if(@$path[0]== $request->getControllerName())
        {
            unset($path[0]);
        }
        if(@$path[1] == $request->getActionName())
        {
            unset($path[1]);
        }
        return $path;
    }
    

    现在是一个像 /mycontroller/myaction/123/321

    在我的操作中,我将获得以下控制器和操作的所有参数

    public function editAction($param1 = null, $param2 = null)
    {
        // $param1 = 123
        // $param2 = 321
    }
    

    URL中的额外参数不会导致任何错误,因为您可以向随后定义的方法发送更多参数。你可以把它们都弄到手 func_get_args() 你仍然可以使用 getParam() 以通常的方式。 您的URL可能不包含使用默认名称的操作名称。

    实际上,我的URL不包含参数名。只有他们的价值观。(与问题中的情况一模一样) 您必须定义路由来指定URL中的参数位置,以遵循框架的概念,并能够使用Zend方法构建URL。 但是,如果您总是知道参数在URL中的位置,那么您可以很容易地得到它。

    这并不像使用反射方法那样复杂,但我想它提供的开销更少。

    分派方法现在如下所示:

    /**
     * Dispatch the requested action
     *
     * @param string $action Method name of action
     * @return void
     */
    public function dispatch($action)
    {
        // Notify helpers of action preDispatch state
        $this->_helper->notifyPreDispatch();
    
        $this->preDispatch();
        if ($this->getRequest()->isDispatched()) {
            if (null === $this->_classMethods) {
                $this->_classMethods = get_class_methods($this);
            }
    
            // preDispatch() didn't change the action, so we can continue
            if ($this->getInvokeArg('useCaseSensitiveActions') || in_array($action, $this->_classMethods)) {
                if ($this->getInvokeArg('useCaseSensitiveActions')) {
                    trigger_error('Using case sensitive actions without word separators is deprecated; please do not rely on this "feature"');
                }
                //$this->$action();
                call_user_func_array(array($this,$action), $this->getUrlParametersByPosition()); 
            } else {
                $this->__call($action, array());
            }
            $this->postDispatch();
        }
    
        // whats actually important here is that this action controller is
        // shutting down, regardless of dispatching; notify the helpers of this
        // state
        $this->_helper->notifyPostDispatch();
    }    
    
        4
  •  3
  •   Andy    16 年前

    要获得允许更复杂配置的更简单方法,请尝试 this post . 总之:

    application/configs/routes.ini

    routes.popular.route = popular/:type/:page/:sortOrder
    routes.popular.defaults.controller = popular
    routes.popular.defaults.action = index
    routes.popular.defaults.type = images
    routes.popular.defaults.sortOrder = alltime
    routes.popular.defaults.page = 1
    routes.popular.reqs.type = \w+
    routes.popular.reqs.page = \d+
    routes.popular.reqs.sortOrder = \w+
    

    bootstrap.php

    // create $frontController if not already initialised
    $frontController = Zend_Controller_Front::getInstance(); 
    
    $config = new Zend_Config_Ini(APPLICATION_PATH . ‘/config/routes.ini’);
    $router = $frontController->getRouter();
    $router->addConfig($config,‘routes’);
    
        5
  •  1
  •   Jeffrey04 George    16 年前

    http://cslai.coolsilon.com/2009/03/28/extending-zend-framework/

    我目前的解决办法如下:

    abstract class Coolsilon_Controller_Base 
        extends Zend_Controller_Action { 
    
        public function dispatch($actionName) { 
            $parameters = array(); 
    
            foreach($this->_parametersMeta($actionName) as $paramMeta) { 
                $parameters = array_merge( 
                    $parameters, 
                    $this->_parameter($paramMeta, $this->_getAllParams()) 
                ); 
            } 
    
            call_user_func_array(array(&$this, $actionName), $parameters); 
        } 
    
        private function _actionReference($className, $actionName) { 
            return new ReflectionMethod( 
                $className, $actionName 
            ); 
        } 
    
        private function _classReference() { 
            return new ReflectionObject($this); 
        } 
    
        private function _constructParameter($paramMeta, $parameters) { 
            return array_key_exists($paramMeta->getName(), $parameters) ? 
                array($paramMeta->getName() => $parameters[$paramMeta->getName()]) : 
                array($paramMeta->getName() => $paramMeta->getDefaultValue()); 
        } 
    
        private function _parameter($paramMeta, $parameters) { 
            return $this->_parameterIsValid($paramMeta, $parameters) ? 
                $this->_constructParameter($paramMeta, $parameters) : 
                $this->_throwParameterNotFoundException($paramMeta, $parameters); 
        } 
    
        private function _parameterIsValid($paramMeta, $parameters) { 
            return $paramMeta->isOptional() === FALSE 
                && empty($parameters[$paramMeta->getName()]) === FALSE; 
        } 
    
        private function _parametersMeta($actionName) { 
            return $this->_actionReference( 
                    $this->_classReference()->getName(), 
                    $actionName 
                ) 
                ->getParameters(); 
        } 
    
        private function _throwParameterNotFoundException($paramMeta, $parameters) { 
            throw new Exception(”Parameter: {$paramMeta->getName()} Cannot be empty”); 
        } 
    }