【问题标题】:Zend - Conditionally reroute all pagesZend - 有条件地重新路由所有页面
【发布时间】:2011-05-11 21:00:44
【问题描述】:

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

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

这是我想要的:

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

// else, continue dispatch as normal...

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

【问题讨论】:

    标签: zend-framework redirect reroute


    【解决方案1】:

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

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

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

    或者你可以把 if 语句放在 index.php 的顶部,避免完全加载框架

    【讨论】:

    • +1 是一个简单的解决方案,但由于需要处理一些更复杂的问题,我选择了插件
    • 不,大约是 1/16。 OP 想要一个启动页面,直到日期 X(或午夜的中风,或其他)。日期条件不依赖于应用程序中的任何内容,因此使用比严格必要的更多的东西会产生过度设计的恶臭。
    • 如果你真的想获得技术,你应该有一个登陆页面,并在另一台具有不同域/子域的机器上拥有你的框架
    • @Ascherer - 这是一个非常好的解决方案,但我不同意一个“应该”这样做,而不是我的建议,或者交换 httpd.conf 并重新启动 apache 的 cron 作业(管他呢)。给猫剥皮等多种方法。
    • 我没有说它不起作用,我只是暗示这不是它“应该”完成的方式
    【解决方案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"
    

    当然,对于类名前缀和文件位置的其他首选项/要求将需要稍微不同的自动加载和调用步骤。

    【讨论】:

    • preDispatch 为时已晚。您可以使用 routeStartup()
    • +1 @Tomáš Fejfar 这是一个很好的观点。除非条件实际上取决于正在完成的路由。但你是对的:我从原始问题的推断是routeStartup() 更好。改变答案。谢谢! ;-)
    • 感谢@David Weinraub,我选择了基于您的解决方案。我必须检查初始请求的目的是为了确保我没有无限重定向,而且我似乎只能在 preDispatch() 中做到这一点,而不是在 routeStartup() 中。查看我的解决方案,让我知道您的想法。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      感谢@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 中没有可用的模块、控制器和操作名称,这是确保我们不会再次将请求重定向到启动页面所必需的(导致无限重定向循环)

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

      【讨论】:

        猜你喜欢
        • 2011-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-25
        • 2021-08-13
        • 2020-09-09
        • 1970-01-01
        • 2014-02-07
        相关资源
        最近更新 更多