2017-06-22 3 views
0

Ich habe eine Seite in meiner Website (zendframework 1), die den GET-Parameter analysiert und seine Daten aus der Datenbank abfragt, um es dem Benutzer zu zeigen.zendframework routing basierend auf dem GET-Parameter

-> my current url : https://example.com/index.php/product/info?id=123 

ich will mein url mehr Menschen lesbare

-> https://example.com/index.php/product/iphone-7s-white 

so sein basicaly ich will die GET-Parameter in der URL analysieren und den Namen des Produkts aus der Datenbank, um abzufragen, um es erscheint als der Seitenname in der URL.

Ich bin auf einige Lösungen gestoßen, eine von ihnen wird durch das Durchlaufen der Datenbank (in bootstrap.php) und Hinzufügen einer Route für jedes Produkt erreicht, aber das scheint wie ein Durcheinander, (Produkte können 200k oder vielleicht mehr als erreichen Das).

Gibt es eine bessere Lösung für mein Problem? Danke im Voraus

+0

Sie könnten einen Slug in Ihrer Produkttabelle haben und dann versuchen, die Zeile mit dem Slug zu erhalten, die dem Parameter route entspricht. Haben Sie das versucht und wenn nicht wo stecken Sie fest? –

+0

Ich kann einfach nicht herausfinden, wie man die Bootstrap-Sache basierend auf den Get Params. der Slug ist im Grunde der Produktname + das Datum –

Antwort

0

Also im Grunde bietet ZF1 eine Standardroute, die zum Controller/Aktion der Namen von der URL führt.

Sie können benutzerdefinierte Routen aus der application/Bootstrap.php Datei hinzufügen, dass es durch das Hinzufügen einer Funktion:

/** 
* This method loads URL routes defined in /application/configs/routes.ini 
* @return Zend_Router 
*/ 
protected function _initRouter() { 
    $this->bootstrap('frontController'); 
    $front = $this->getResource('frontController'); 
    $router = $front->getRouter(); 
    $router->addRoute(
     'user', 
     new Zend_Controller_Router_Route('product/:slug', array(
      'controller' => 'product', 
      'action'  => 'details', 
     ), array(
      'slug' => '[A-Za-z0-9-]+', 
     )) 
    ); 
    return $router; 
} 

Und hier gehen Sie!


Wie von Chris beschrieben, müssen Sie Ihren Controller-Code ändern, um die Anfrage zu bearbeiten. Eine andere Lösung wäre eine zusätzliche Aktion.

final class ProductController 
{ 
    public function infoAction() 
    { 
     $product = $table->find($this->_param('id')); 
     $this->view->product = $product; 
    } 

    public function detailsAction() 
    { 
     $product = $table->fetch(['slug' => $this->_param('slug')]); 
     $this->view->product = $product; 
     $this->render('info'); 
    } 
} 

Nun, vorausgesetzt, Sie in infoAction viel Verarbeitung tun, könnten Sie mit einem nach vorne gehen:

final class ProductController 
{ 
    public function infoAction() 
    { 
     $product = $table->find($this->_param('id')); 
     $this->view->product = $product; 
    } 

    public function detailsAction() 
    { 
     $product = $table->fetch(['slug' => $this->_param('slug')]); 
     $this->forward('info', 'product', [ 
      'id' => $product->id, 
     ]); 
    } 
} 

Es ist weniger effizient (2 Anfragen statt eins), sondern ermöglicht es Ihnen, wieder zu verwenden dein Code.

+0

hey, danke für Ihre Antwort, könnten Sie weiter den Code, den Sie geschrieben haben. Ich verstehe den Slug Part nicht vollständig, wie soll er die ID in der ursprünglichen URL ersetzen? –

+2

Die Idee ist, dass Sie einen Slug in Ihrer DB speichern müssen, der Slug ist der Titel Ihres Artikels und muss ein PK (oder ein Unikat) sein, damit Sie abfragen können. Dann wird diese Route diesen Controller auslösen und einen Slug-Parameter für Sie übergeben, dann müssen Sie Ihre Datenbank abfragen, wo slug => $ slug, und wenn Sie nicht gefunden werden, lösen Sie einen 404-Fehler aus, sonst zeigen Sie das Produkt an. – Chris

+0

Bearbeitet nach Ihrem Kommentar Chris. Ich würde argumentieren, dass der Slug kein Primärschlüssel sein muss, sondern ein eindeutiger Index sein muss, um effizient suchen zu können. –

Verwandte Themen