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

时间:2020-03-06 15:00:58  来源:igfitidea点击:

在Kohana / CodeIgniter中,我可以使用以下形式的URL:

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

我们如何在Zend框架中实现这一目标?

解决方案

看一下Zend_Controller_Router类:

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

这些将使我们能够定义Zend_Controller_Router_Route,该Zend_Controller_Router_Route以我们需要的方式映射到URL。

为Index控制器的Index操作具有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');

在操作方法内访问值。

安德鲁

更新(04/13/2016):
我下面的答案中的链接已移动,并且已修复。但是,以防万一它再次消失-这里有一些替代方法,它们提供了有关此技术的深入信息,并使用原始文章作为参考资料:

  • 具有功能参数的Zend Framework Controller操作
  • Zend_Controller动作可以接受参数吗?

@Andrew Taylor的响应是处理URL参数的正确Zend Framework方法。但是,如果我们想在控制器的操作中包含URL参数(如示例所示),请查看有关Zend DevZone的本教程。

最初发布在这里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”); 
    } 
}

有关允许进行更复杂配置的更简单方法,请尝试本文。总之:

创建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’);