2008-10-02 6 views
12

In Kohana/CodeIgniter, kann ich eine URL in dieser Form haben:URL verwenden Segmente als Aktionsmethode Parameter in Zend Framework

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

Und dann die Parameter in meinem Controller wie folgt lauten:

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

Wie erreichst du das im Zend Framework?

Antwort

6

Update (2016.04.13): Der Link in meiner Antwort unten bewegt und wurde behoben. Allerdings nur, falls es wieder verschwindet - hier sind ein paar Alternativen, die einige ausführliche Informationen über diese Technik zur Verfügung stellen, sowie der Original-Artikel als Referenzmaterial verwenden:


@Andrew Taylor Antwort ist die richtige Zend Framework Art der Behandlung von URL-Parametern. Wenn Sie jedoch die URL-Parameter in der Aktion Ihres Controllers haben möchten (wie in Ihrem Beispiel), überprüfen Sie this tutorial on Zend DevZone.

11

Werfen Sie einen Blick auf die Zend_Controller_Router Klassen:

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

Diese ermöglicht es Ihnen, eine Zend_Controller_Router_Route, die in der Art und Weise, um Ihre URL-Karten zu definieren, die Sie benötigen.

Ein Beispiel für den Index Aktion des Index-Controller 4 statisches params mit ist:

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

Diese in der Bootstrap hinzugefügt wird, nachdem Sie Ihren Front-Controller definiert haben.

Nachdem Sie in Aktion können Sie dann verwenden:

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

In Ihrer Aktion-Methode die Werte zuzugreifen.

Andrew

+0

Nizza, die Dokumentation in der Hinsicht nicht so klar sind. –

1

Ursprünglich hier gepostet http://cslai.coolsilon.com/2009/03/28/extending-zend-framework/

Meine aktuelle Lösung ist wie folgt:

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

Für eine einfachere Methode, die für komplexere Konfigurationen ermöglicht, versuchen this post.Zusammengefasst:

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

hinzufügen 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

aber dann müsste ich für jeden Controller konfigurieren: D – Jeffrey04

+0

das ist oft nützlich, ich neige dazu, Controller und Routengruppe gut zusammen zu finden, dh/page/get/1 und/user/andy/confirm/email-confirmation-token etc, obwohl für größere Anwendungen kann es unhandlich werden – Andy

4

ich Zend_Controller_Action mit meinem Controller-Klasse erweitert und folgende Änderungen vorgenommen:

In dispatch($action) Verfahren ersetzt

$this->$action();

mit

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

und addierten die folgenden Verfahren

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

nun für eine URL wie /mycontroller/myaction/123/321

in meiner Aktion, die ich alle params folgende Controller erhalten und Aktion

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

Zusätzliche Parameter in der URL verursachen keinen Fehler, da Sie mehr Parameter an die Methode senden können, die dann definiert werden. Sie können alle durch func_get_args() bekommen und Sie können getParam() in einer üblichen Weise noch verwenden. Ihre URL darf keinen Aktionsnamen mit dem Standardnamen enthalten.

Meine URL enthält eigentlich keine Parameternamen. Nur ihre Werte. (Genau wie es in der Frage war) Und Sie müssen Routen definieren, um Parameterpositionen in URL anzugeben, um den Konzepten des Frameworks zu folgen und URLs mit Zend-Methoden erstellen zu können. Aber wenn Sie immer die Position Ihres Parameters in URL kennen, können Sie es leicht so erhalten.

Das ist nicht so raffiniert wie die Verwendung von Reflektionsmethoden, aber ich denke, es bietet weniger Overhead.

Dispatch-Methode sieht nun wie folgt aus:

/** 
* 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, sieht gut aus :) – Jeffrey04