【问题标题】:Yii2: Best method to intercept 404 and do 301 redirect to new page?Yii2:拦截404并将301重定向到新页面的最佳方法?
【发布时间】:2021-01-15 19:32:08
【问题描述】:

出于 SEO 的目的,我想将旧的非 Yii2 URL 重定向到新的 URL。所以我需要拦截 Yii 抛出的 404 并以 301 重定向响应。最好的地方在哪里?

【问题讨论】:

    标签: php yii2 http-status-code-301


    【解决方案1】:

    你可以创建一个实现 yii\web\UrlRuleInterface 的类。该接口需要两个函数:

    1. parseRequest:使用此方法检查请求是否匹配旧 url。如果是,则重定向到新的 url,否则返回 false。您可以根据需要检查数据库表或旧网址列表。
    2. createUrl:由于这些旧的 url 不再起作用,createUrl 只需要返回 false。
    public function createUrl($manager, $route, $params)
    {
        return false; // this rule does not apply
    }
    

    另外,我会把它作为你的 UrlManager 规则的最后一条规则,这样它就不会影响你的其他页面,无论是性能还是隐藏新的 url。

    完整解释请参见 Yii 文档:https://www.yiiframework.com/doc/guide/2.0/en/runtime-routing#creating-rules

    【讨论】:

      【解决方案2】:

      我会将旧 URL 添加到 config/url-manager.php(或在高级模板的情况下为 backend/config/url-manager.php)以通过适当的控制器操作处理它们,并在控制器中进行重定向。

      举个例子,假设启用了漂亮的 URL,旧的 URL 是 posts/list,新的 URL 是简单的 posts,然后在 url-manager 的规则中添加以下内容:

      'posts/list' => 'posts/post/index-redirect',
      'posts' => 'posts/post/index',
      

      这会将旧 URL 路由到帖子模块的 PostController。将以下操作添加到控制器:

      public function actionIndexRedirect()
      {
          return $this->redirect(['index'], 301);
      }
      

      当然,您可能有很多旧 URL,并且您不想一个一个地处理它们,而是将参数添加到规则并在重定向操作中处理参数。

      【讨论】:

      • 这可能是解决它的一种方法是的。我只是不喜欢非原子方法。只想控制一个地方 - 为了更好的可维护性。
      【解决方案3】:

      到目前为止,我自己发现了这些可能的方法:

      方法一:

      此方法在处理请求之前执行 - 基于已知的 URL。它们仅在 URL 不直接指向现有文件/文件夹时生效(否则.htaccess 将永远不会将 rquest 重定向到 Yii)。

      config/web.php 中将以下内容添加到配置数组中:

      $config = [
          'id' => '...',
          'components' => '...',
          'params' => '...',
          ...
          'on beforeAction' => function($event) {
              $redirects = [
                  'your/old/url.php' => '/my/new-route',
                  'contact.php' => '/site/contact',
              ];
              if (($newRoute = $redirects[Yii::$app->requestedRoute]) || ($newRoute = $redirects[Yii::$app->requestedRoute .'/'])) {
                  // maybe you want to add some logging here on this line
                  Yii::$app->response->redirect(\yii\helpers\Url::to($newRoute), 301);
                  Yii::$app->end();
              }
          },
      ];
      

      方法二:

      此方法在处理请求之后执行它 - 基于无路由并以 404 结尾。这样做的优点是我们还可以处理以 404 结尾的未知 URL .

      根据文档 herehere 添加引导类。然后将其添加到您的 bootstrap() 方法中:

      Yii::$app->on(\yii\web\Application::EVENT_BEFORE_ACTION, function($event) use (&$app) {
          if ($event->sender->getStatusCode() == 404) {
              // maybe you want to add some logging here on this line
              if (in_array($app->requestedRoute, ['your/old/url.php', 'contact.php'])) {
                  // determine new route and redirect the same way as we do in method 1
              } else {
                  // here you do redirect eg. to the homepage or do nothing if you still want to throw a 404
              }
          }
      });
      

      Here 也是另一个变体。

      【讨论】:

        猜你喜欢
        • 2012-04-13
        • 1970-01-01
        • 2017-05-08
        • 2015-06-22
        • 2011-10-31
        • 1970-01-01
        • 2018-05-03
        • 2017-08-07
        • 1970-01-01
        相关资源
        最近更新 更多