Utiliser les segments d'URL comme paramètres de méthode d'action dans Zend Framework

StackOverflow https://stackoverflow.com/questions/161443

  •  03-07-2019
  •  | 
  •  

Question

Dans Kohana / CodeIgniter, je peux avoir une URL sous la forme suivante:

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

Et lisez ensuite les paramètres de mon contrôleur comme suit:

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

Comment réalisez-vous cela dans le Zend Framework?

Était-ce utile?

La solution

Mise à jour (13/04/2016): Le lien dans ma réponse ci-dessous déplacé et a été corrigé. Cependant, juste au cas où elle disparaîtrait encore, voici quelques alternatives qui fournissent des informations détaillées sur cette technique, ainsi que l'article d'origine comme matériau de référence:

@ Andrew Taylor response est le moyen approprié pour Zend Framework de gérer les paramètres d’URL. Toutefois, si vous souhaitez que les paramètres d'URL soient utilisés dans l'action de votre contrôleur (comme dans votre exemple), accédez à ce tutoriel sur Zend DevZone .

Autres conseils

Jetez un coup d'œil aux classes Zend_Controller_Router:

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

Celles-ci vous permettront de définir un Zend_Controller_Router_Route qui correspond à votre URL de la manière dont vous avez besoin.

Voici un exemple de configuration paramétrique statique pour l'action Index du contrôleur d'index:

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

Ceci est ajouté à votre boot après que vous ayez défini votre contrôleur frontal.

Une fois dans votre action, vous pouvez ensuite utiliser:

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

Dans votre méthode d'action pour accéder aux valeurs.

Andrew

J'ai étendu Zend_Controller_Action avec ma classe de contrôleur et apporté les modifications suivantes:

Dans la méthode dispatch ($ action) remplacée

$ this- > $ action ();

avec

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

Et ajouté la méthode suivante

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

Maintenant, pour une URL du type / mycontroller / myaction / 123/321

dans mon action, j'obtiendrai tous les paramètres suivants du contrôleur et de l'action

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

Les paramètres supplémentaires dans l'URL ne causeront aucune erreur car vous pouvez envoyer plus de paramètres à la méthode alors définie. Vous pouvez tous les obtenir par func_get_args () Et vous pouvez toujours utiliser getParam () de manière habituelle. Votre URL ne peut pas contenir le nom de l'action en utilisant celui par défaut.

En fait, mon URL ne contient pas de noms de paramètres. Seulement leurs valeurs. (Exactement comme c'était dans la question) Et vous devez définir des itinéraires pour spécifier les positions des paramètres dans l'URL afin de suivre les concepts de structure et de pouvoir créer des URL à l'aide de méthodes Zend. Mais si vous connaissez toujours la position de votre paramètre dans l'URL, vous pouvez facilement l'obtenir ainsi.

Ce n’est pas aussi sophistiqué que d’utiliser des méthodes de réflexion, mais j’imagine que cela génère moins de frais généraux.

La méthode de répartition ressemble maintenant à ceci:

/**
 * 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();
}    

Pour une méthode plus simple permettant des configurations plus complexes, essayez cet article . En résumé:

Créer 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+

Ajouter à 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’);

Initialement posté ici http://cslai.coolsilon.com / 2009/03/28 / extend-zend-framework /

Ma solution actuelle est la suivante:

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”); 
    } 
} 
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top