使用 PHP 重定向几千个 URL

Redirecting a few thousand URLs using PHP

我正在迁移一个需要大约 5000 次重定向的站点,格式如

http://www.acme.org/content/item.aspx?id=123 重定向到 http://www.acme.org/resources/articles/why-acme-is-great

通常我会通过 .htaccess 或 nginx 模块完成此操作。但是我在 WordPress 特定主机 Pantheon 上,它不允许访问它。

所以我能想到的唯一解决办法就是使用PHP。以下是工作。那里有一些特定于 WordPress 的代码可以防止 WordPress 抛出 404。

add_filter('template_redirect', 'my_404_override');
function my_404_override()
{
  global $wp_query;
  if (strpos($_SERVER['REQUEST_URI'], 'issues') !== false) {
    $redirectURL = "/resources";
    if (strpos($_SERVER['REQUEST_URI'], '123') !== false) {
      $redirectURL .= "/articles/why-acme-is-great/";
    }
  }

  if (!empty($redirectURL)) {
    status_header(200);
    $wp_query->is_404 = false;
    header('HTTP/1.0 301 Moved Permanently');
    header('Location: http://www.acme.org' . $redirectURL);
  }
}

这很好用。但是我有两个问题:

  1. 有5000个列表,这对性能会有什么样的影响?我打算使用一些更大的条件,然后缩小范围(在上面的示例中,我首先检查 /resources,然后再查看特定 ID。
  2. 虽然理论上永远不需要修改此列表,但就语法和逻辑而言,它感觉像是一个丑陋的解决方案。有没有我没有想到的更好的方法?

您的问题是您需要将旧内容映射到新内容。将自定义字段添加到每个 post 内容以达到 "old_url=123" 的效果,然后为 post-slug 执行 wp_query。我假设您的旧 ID(即 123)不一定与新 ID 匹配。为每个可能的 URL 添加条件的方法不可行且难以维护。

当您为每个包含 "old content" 的新 post / 页面添加一个字段时,您的代码可以是这样的:

add_filter('template_redirect', 'my_404_override');
function my_404_override()
{
   global $wp_query;
   $old_url = $_SERVER['REQUEST_URI'];
   $results = $wpdb->get_results(
        $wpdb->prepare( "SELECT wp_posts.guid, redirect_url FROM wp_posts LEFT JOIN wp_post_meta ON wp_posts.ID = wp_post_meta.post_id WHERE wp_post_meta.old_url = %s LIMIT 1", $old_url ));
     $redirectURL = $results[0]['guid'];
  }

if (!empty($redirectURL)) {
    status_header(200);
    $wp_query->is_404 = false;
    header('HTTP/1.0 301 Moved Permanently');
    header('Location: ' . $redirectURL);
    }
}

这是伪代码;但一般的想法是无论如何都要查询一行;并且对性能的影响可以忽略不计,因为只有在 404 的情况下,您检查是否存在重定向并且该查询 returns 只有一行。

这种方法存在问题,例如,如果某人在两个 post 上输入相同的数字,则无法确定哪个是最重要的重定向的优先级。您也可以考虑使用插件来解决这个问题。

https://wordpress.org/plugins/redirection/