A Genel, catch-all Zend Framework eylem ...

9 Cevap php

Bu durum ilgili eylemleri oluşturma içine almak zorunda kalmadan kendi web sitesinde kendi "sayfalar" oluşturmak isteyen birinden doğar.

Yani ... onlar mysite.com / index / booksmore veya mysite.com / index / krep oluşturmak, ancak endeks denetleyicisi herhangi eylemler oluşturmak zorunda değil muktedir istiyorum onlar mysite.com / index / kitap gibi bir URL var demek . Onlar (basit html yapabileceği bir teknik olmayan kişi) temelde bir eylem kullanmak zorunda kalmadan, basit, statik bir sayfa oluşturmak istiyorum.

Gibi var olmayan bir eylem için istekleri işleyen endeksi denetleyicisi bazı genel eylem olurdu. Bu ya da bile mümkün nasıl yaparsınız?

__ Çağrısı kullanarak edit: Bir sorun bir görünüm dosyasının olmamasıdır. Bir eylemin olmaması tartışma olur ama şimdi eksik görünüm dosyası ile uğraşmak zorunda. O birini bulamazsa (eksik görünüm dosyası __ çağrı üzerine bir 404 yönlendirme almak için bir yolu var olsaydı yapılabilir olacaktır gerçi.) Çerçeve bir istisna atar

9 Cevap

You have to play with the router http://framework.zend.com/manual/en/zend.controller.router.html

Ben belirli bir modül üzerinde her eylem yakalamak (varsayılan bir url azaltmak için) ve url göre görünümü render (denir hatta eylem) ilgilenecek bir eylemi tanımlamak için bir joker belirtebilirsiniz düşünüyorum

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

in you customAction function just retrieve the params and display the right block. I haven't tried so you might have to hack the code a little bit

Büyü kullanarak __call yöntemi çalışıyor, yapmanız gereken tüm görünüm dosyası olup olmadığını kontrol edin ve doğru istisna (veya başka enything yok) değilse değildir.

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

Eğer gabriel1836 en _call kullanmak istiyorsanız () yöntemi düzeni ve görünümü devre dışı bırakın ve sonra istediğiniz ne olursa olsun işlemek gerekir.

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

Ben mevcut modül / denetleyici / eylemler Zend Framework uygulaması normal çalışma için gerekli, ancak daha sonra bir veritabanı tablosunun üzerinden kullanıcı belirtilen adresler almak ve sayfayı görüntülemek olabilecek bir PageController bilinmeyen bir şey gönderilen herkesi kucaklayan yol var. Ben kullanıcı belirtilen adresler önünde bir kontrolör adı var istemiyordu. PageController yoluyla gitmek istediğim / benim / özel / url değil / sayfa / benim / özel / url. Yani yukarıdaki çözümlerin hiçbiri benim için çalıştı.

Hemen hemen tüm varsayılan davranışı kullanarak ve biraz bu yüzden denetleyici adını verdiği denetleyici dosya varsa normal olarak buna biz yol: Ben Zend_Controller_Router_Route_Module uzanan kadar sona erdi. O yok, o url garip bir özel biri olmalı, bu yüzden bir parametre olarak bozulmamış bütün url ile PageController gönderilen alır.

class UDC_Controller_Router_Route_Catchall extends Zend_Controller_Router_Route_Module
{
    private $_catchallController = 'page';
    private $_catchallAction     = 'index';
    private $_paramName          = 'name';

    //-------------------------------------------------------------------------
    /*! \brief takes most of the default behaviour from Zend_Controller_Router_Route_Module
        with the following changes:
        - if the path includes a valid module, then use it
        - if the path includes a valid controller (file_exists) then use that
            - otherwise use the catchall
    */
    public function match($path, $partial = false)
    {
        $this->_setRequestKeys();

        $values = array();
        $params = array();

        if (!$partial) {
            $path = trim($path, self::URI_DELIMITER);
        } else {
            $matchedPath = $path;
        }

        if ($path != '') {
            $path = explode(self::URI_DELIMITER, $path);

            if ($this->_dispatcher && $this->_dispatcher->isValidModule($path[0])) {
                $values[$this->_moduleKey] = array_shift($path);
                $this->_moduleValid = true;
            }

            if (count($path) && !empty($path[0])) {
                $module = $this->_moduleValid ? $values[$this->_moduleKey] : $this->_defaults[$this->_moduleKey];
                $file = $this->_dispatcher->getControllerDirectory( $module ) . '/' . $this->_dispatcher->formatControllerName( $path[0] ) . '.php'; 
                if (file_exists( $file ))
                {
                    $values[$this->_controllerKey] = array_shift($path);
                }
                else
                {
                    $values[$this->_controllerKey] = $this->_catchallController;
                    $values[$this->_actionKey] = $this->_catchallAction;
                    $params[$this->_paramName] = join( self::URI_DELIMITER, $path );
                    $path = array();
                }
            }

            if (count($path) && !empty($path[0])) {
                $values[$this->_actionKey] = array_shift($path);
            }

            if ($numSegs = count($path)) {
                for ($i = 0; $i < $numSegs; $i = $i + 2) {
                    $key = urldecode($path[$i]);
                    $val = isset($path[$i + 1]) ? urldecode($path[$i + 1]) : null;
                    $params[$key] = (isset($params[$key]) ? (array_merge((array) $params[$key], array($val))): $val);
                }
            }
        }

        if ($partial) {
            $this->setMatchedPath($matchedPath);
        }

        $this->_values = $values + $params;

        return $this->_values + $this->_defaults;
    }
}

Yani benim MemberController / member / login gibi, / member / tercihleri ​​vb, ve diğer kontrolörler irade eklenebilir iyi çalışır. ErrorController hala gereklidir: varolan denetleyicileri üzerinde geçersiz eylemleri yakalar.

Sen sihirli __call() function kullanabilirsiniz. Örneğin:

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

stunti önerisi Ben bu ile gitti yoluydu. (. Bu belirttiğiniz) hangisi kontrolör (indexAction kullanan benim durumda her eylem indexAction kullanıyordum ve url dayalı bir veritabanından içerik çekerek) aşağıdaki gibi benim özellikle bir çözümdür:

  1. Yönlendirici bir örneğini (her şeyi btw, sizin önyükleme dosyasında) olsun:

    $ Yönlendirici = $ frontController-> getRouter ();

  2. Özel rota oluşturmak:

    $ Router-> addRoute ('ControllerName', yeni Zend_Controller_Router_Route ('ControllerName / *', array ('controller' => 'ControllerName')));

  3. Ön denetleyiciye yeni rota Pass:

    $ FrontController-> setRouter ($ yönlendirici);

Hala kayıp gelen görünüm dosyası ile ilgili bir hata atar çünkü ben (sürece bir görünüm dosyası gerekmez gibi yöntemler eksik çalışır) Gabriel'in __ çağrı yöntemi ile gitmedi.

İleride, gabriel1836 bina ve ejunker düşünceleri, ben daha fazla noktaya alır (ve MVC paradigma onadı) bir seçeneği kazılıp. Ayrıca, "herhangi bir görünümü kullanmayın" daha okumak "özel görünümü kullanmak" daha mantıklı.


// 1. Catch & process overloaded actions.
public function __call($name, $arguments)
{
    // 2. Provide an appropriate renderer.
    $this->_helper->viewRenderer->setRender('overload');
    // 3. Bonus: give your view script a clue about what "action" was requested.
    $this->view->action = $this->getFrontController()->getRequest()->getActionName();
}

Ben gönderme yöntemi geçersiz ve eylem bulunamadı atılır, özel durum işleme ile bir catch-all uygulanmaktadır:

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');
    }
}

@ Steve yukarıdaki gibi - çözüm benim için ideal geliyor ama bootstrap bunu implmeented nasıl emin değilim?