2008-10-02 6 views

Répondre

6

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


@Andrew Taylor La réponse de Zend Framework est la bonne façon de gérer les paramètres d'URL. Cependant, si vous souhaitez avoir les paramètres d'URL dans l'action de votre contrôleur (comme dans votre exemple) - consultez this tutorial on Zend DevZone.

11

Jetez un oeil à la classe Zend_Controller_Router:

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

Ceux-ci vous permettra de définir une Zend_Controller_Router_Route qui mappe à votre URL de la façon dont vous avez besoin.

Un exemple d'avoir 4 params statiques pour l'action index du contrôleur d'index est:

$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 bootstrap après que vous avez défini votre contrôleur avant.

Une fois dans votre action, vous pouvez utiliser:

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

l'intérieur de votre méthode d'action pour accéder aux valeurs.

Andrew

+0

Nice, les documents ne sont pas si claires à l'égard. –

1

Initialement posté ici http://cslai.coolsilon.com/2009/03/28/extending-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”); 
    } 
} 
3

Pour une méthode plus simple qui permet des configurations plus complexes, essayez this post.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’); 
+0

mais alors je devrais config pour chaque contrôleur: D – Jeffrey04

+0

qui est souvent utile, j'ai tendance à trouver des contrôleurs et route le groupe bien ensemble ie/page/get/1 et/user/andy/confirm/email-confirmation-token etc, Bien que pour les applications plus importantes, il peut devenir lourd – Andy

4

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

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

$this->$action();

avec

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

et a 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 comme /mycontroller/myaction/123/321

dans mon action, je vais obtenir tous les params suivants contrôleur et action

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

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

En fait, mon URL ne contient pas de noms de paramètres. Seules leurs valeurs. (Exactement comme c'était dans la question) Et vous devez définir des routes pour spécifier les positions des paramètres dans l'URL pour suivre les concepts de framework et pouvoir construire des URL en utilisant les méthodes Zend. Mais si vous connaissez toujours la position de votre paramètre dans l'URL, vous pouvez facilement l'obtenir comme ceci.

Ce n'est pas aussi sophistiqué que l'utilisation de méthodes de réflexion, mais je suppose que cela fournit moins de frais généraux.

méthode d'expédition 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(); 
}  
+0

hey, a l'air bien :) – Jeffrey04

Questions connexes