Zend - 有条件地重新路由所有页面

时间:2011-05-11 21:00:44

标签: zend-framework redirect reroute

如果条件通过,我希望能够将我的网站的所有请求重新路由或重定向到特定页面。我假设这必须在引导程序或调度程序的某个地方完成,但我不确定最好/最干净的方法是什么。

没有.htaccess重定向,因为需要在PHP中测试条件

这是我想要的:

if( $condition ) {
    // Redirect ALL Pages/Requests
}

// else, continue dispatch as normal...

这里的想法是我们可以设置整个网站并将所有内容发送到启动页面,直到指定的日期/时间,此时它本身将“自动启动”。

4 个答案:

答案 0 :(得分:5)

为什么要打扰路由?只是一个简单的重定向。

在Bootstrap.php中可能是这样的:

public function initSplash(){
    if($splashtime && $requestIsNotForComingSoonAlready){
        header('Location: /coming-soon',true,302);
        die();
    }
}

或者您可以将if语句粘贴在index.php的顶部,并避免完全加载框架

答案 1 :(得分:2)

的确,我会选择一个插件。

library/My/Plugin/ConditionallyRedirect.php

class My_Plugin_ConditionallyRedirect extends Zend_Controller_Plugin_Abstract
{
    public function routeStartup(Zend_Http_Request_Abstract $request)
    {
        // perform your conditional check
        if ($this->_someCondition()){
             $front = Zend_Controller_Front::getInstance();
             $response = $front->getResponse();
             $response->setRedirect('/where/to/go');
        }
    }

    protected function _someCondition()
    {
        // return the result of your check
        return false; // for example
    }

}

然后在application/configs/application.ini注册您的插件:

autoloaderNamespaces[]                        = "My_"
resources.frontController.plugins.conditional = "My_Plugin_ConditionallyRedirect"

当然,classname前缀和文件位置的其他首选项/要求会导致自动加载和调用的步骤略有不同。

答案 2 :(得分:1)

如果您想以正确的方式执行此操作,则必须在创建请求后在类中执行此操作,以便在发送响应之前对其进行修改。通常不是在引导程序中。我想把它放在一个可以访问前端控制器的插件(类似于ACL的工作方式)

答案 3 :(得分:1)

谢谢@David Weinraub,我选择了与你类似的插件。我不得不改变一些事情,这是我的最终结果(我的一些应用程序特定的东西在这里简化了示例)

<?php

/**
 * Lanch project within valid dates, otherwise show the splash page
 */

class App_Launcher extends Zend_Controller_Plugin_Abstract
{
// The splash page
private $_splashPage = array(
    'module' => 'default',
    'controller' => 'coming-soon',
    'action' => 'index'
);

// These pages are still accessible
private $_whiteList = array(
    'rules' => array(
        'module' => 'default',
        'controller' => 'sweepstakes',
        'action' => 'rules'
    )
);


/**
 * Check the request and determine if we need to redirect it to the splash page
 * 
 * @param Zend_Controller_Request_Http $request
 * @return void
 */
public function preDispatch(Zend_Controller_Request_Http $request)
{
    // Redirect to Splash Page if needed
    if ( !$this->isSplashPage($request) && !$this->isWhiteListPage($request) && !$this->isSiteActive() ) {

        // Create URL for Redirect
        $urlHelper = new Zend_View_Helper_Url();
        $url = $urlHelper->url( $this->_splashPage );

        // Set Redirect
        $front = Zend_Controller_Front::getInstance();
        $response = $front->getResponse();
        $response->setRedirect( $url );

    }
}


/**
 * Determine if this request is for the splash page
 * 
 * @param Zend_Controller_Request_Http $request
 * @return bool
 */
public function isSplashPage($request) {

    if( $this->isPageMatch($request, $this->_splashPage) )
        return true;

    return false;

}


/**
 * Check for certain pages that are OK to be shown while not 
 * in active mode
 * 
 * @param Zend_Controller_Request_Http $request
 * @return bool
 */
public function isWhiteListPage($request) {

    foreach( $this->_whiteList as $page )
        if( $this->isPageMatch($request, $page) )
            return true;            

    return false;

}


/**
 * Determine if page parameters match the request 
 * 
 * @param Zend_Controller_Request_Http $request
 * @param array $page (with indexes module, controller, index)
 * @return bool
 */
public function isPageMatch($request, $page) {

    if(  $request->getModuleName() == $page['module']
      && $request->getControllerName() == $page['controller']
      && $request->getActionName() == $page['action'] )
        return true;

    return false;
}


/**
 * Check valid dates to determine if the site is active
 * 
 * @return bool
 */
protected function isSiteActive() {

    // We're always active outside of production
    if( !App_Info::isProduction() )
        return true;

    // Test for your conditions here...
    return false; 
            // ... or return true;

}

}

有一些改进的空间,但这符合我现在的需求。旁注,我不得不将函数更改回preDispatch,因为$ request没有routeStartup中可用的模块,控制器和操作名称,这是确保我们不再将请求重定向到启动页面所必需的(导致无限重定向循环)

(还为其他应该仍可访问的网页添加了“白名单”)