4 Stimmen

Eine generische Catch-All-Aktion in Zend Framework... ist das machbar?

Diese Situation entsteht, wenn jemand seine eigenen "Seiten" in seiner Website erstellen möchte, ohne sich mit der Erstellung der entsprechenden Aktionen befassen zu müssen.

Sagen wir, sie haben eine URL wie mysite.com/index/books... sie wollen in der Lage sein, mysite.com/index/booksmore oder mysite.com/index/pancakes zu erstellen, müssen aber keine Aktionen im Index-Controller erstellen. Sie (eine nicht-technische Person, die einfaches Html beherrscht) wollen im Grunde eine einfache, statische Seite erstellen, ohne eine Aktion verwenden zu müssen.

Als gäbe es eine generische Aktion im Index-Controller, die Anfragen für eine nicht existierende Aktion bearbeitet. Wie tun Sie dies oder ist es überhaupt möglich?

bearbeiten: Ein Problem bei der Verwendung von __call ist das Fehlen einer View-Datei. Das Fehlen einer Aktion wird dadurch überflüssig, aber jetzt müssen Sie sich mit der fehlenden Ansichtsdatei befassen. Das Framework wirft eine Ausnahme, wenn es keine finden kann (obwohl, wenn es einen Weg, um es zu einem 404 auf eine fehlende View-Datei umleiten __call wäre machbar).

10voto

Ludwig Punkte 3258

Die Magie nutzen __call Methode funktioniert einwandfrei, Sie müssen nur prüfen, ob die View-Datei existiert und die richtige Ausnahme auslösen (oder etwas anderes tun), wenn nicht.

public function __call($methodName, $params)
{
    // An action method is called
    if ('Action' == substr($methodName, -6)) {
        $action = substr($methodName, 0, -6);

        // We want to render scripts in the index directory, right?
        $script = 'index/' . $action . '.' . $this->viewSuffix;

        // Script file does not exist, throw exception that will render /error/error.phtml in 404 context
        if (false === $this->view->getScriptPath($script)) {
            require_once 'Zend/Controller/Action/Exception.php';
            throw new Zend_Controller_Action_Exception(
                sprintf('Page "%s" does not exist.', $action), 404);
        }

        $this->renderScript($script);
    }

    // no action is called? Let the parent __call handle things.
    else {
        parent::__call($methodName, $params);
    }
}

3voto

stunti Punkte 855

Sie müssen mit dem Router spielen http://framework.zend.com/manual/en/zend.controller.router.html

Ich denke, Sie können einen Platzhalter angeben, um jede Aktion auf ein bestimmtes Modul zu fangen (die Standardeinstellung, um die URL zu reduzieren) und eine Aktion zu definieren, die sich um das Rendern der Ansicht entsprechend der URL (oder sogar der aufgerufenen Aktion) kümmern wird

new Zend_Controller_Router_Route('index/*', 
array('controller' => 'index', 'action' => 'custom', 'module'=>'index') 

in Ihrer customAction-Funktion einfach die Parameter abrufen und den richtigen Block anzeigen. Ich habe nicht versucht, so müssen Sie möglicherweise den Code ein wenig hacken

2voto

ejunker Punkte 10536

Wenn Sie gabriel1836's _call() Methode verwenden möchten, sollten Sie in der Lage sein, das Layout und die Ansicht zu deaktivieren und dann zu rendern, was Sie wollen.

$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);

2voto

curmil Punkte 967

Ich habe einen Auffangmechanismus implementiert, indem ich die Dispatch-Methode überschrieben habe und die Ausnahme behandelt habe, die ausgelöst wird, wenn die Aktion nicht gefunden wird:

public function dispatch($action)
{
    try {
        parent::dispatch($action);
    }
    catch (Zend_Controller_Action_Exception $e) {
        $uristub = $this->getRequest()->getActionName();
        $this->getRequest()->setActionName('index');
        $this->getRequest()->setParam('uristub', $uristub);
        parent::dispatch('indexAction');
    }
}

1voto

Noah Goodrich Punkte 24212

Sie könnten die Magie nutzen __Aufruf() Funktion. Zum Beispiel:

public function __call($name, $arguments) 
{
     // Render Simple HTML View
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X