views:

3145

answers:

4

in Kohana/CodeIgniter, I can have url in this form -> http://www.name.tld/controller_name/method_name/parameter_1/parameter_2/parameter_3 ...

and read the parameters in my controller as follows

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

is there a workaround for this or there is an alternative way in Zend Framework?

+7  A: 

Hi,

Take a look at the Zend_Controller_Router classes:

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

These will allow you to define a Zend_Controller_Router_Route which maps to your URL in the way that you need.

An example of having 4 static params for the Index action of the Index controller is:

$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 is added to your bootstrap after you've defined your front controller.

Once in your action, you can then use:

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

Inside your action method to access the values.

Andrew

Andrew Taylor
Nice, the docs are not so clear in the regard.
sims
+4  A: 

@Andrew Taylor's response is the proper Zend Framework way of handling URL parameters. However, if you would like to have the URL parameters in your controller's action (as in your example) - check out this tutorial on Zend DevZone.

leek
A: 

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

My current solution is as follows:

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”); 
    } 
}
Jeffrey04
+1  A: 

For a simpler method that allows for more complex configurations, try this post. In summary:

Create 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+

Add to 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’);
Andy
but then i would have to config for every controller :D
Jeffrey04
that's often useful, I tend to find controllers and routes group well together i.e. /page/get/1 and /user/andy/confirm/email-confirmation-token etc, although for larger applications it can become unwieldy
Andy