1

I am migrating a site which will require about 5000 redirects, in a format such as

http://www.acme.org/content/item.aspx?id=123 redirects to http://www.acme.org/resources/articles/why-acme-is-great

Normally I would accomplish this through .htaccess or an nginx module. However I'm on a WordPress specific host, Pantheon, which does not allow access to that.

Therefore the only solution I could think of is to use PHP. The following is working. There's some WordPress specific code in there to prevent WordPress from just throwing a 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);
  }
}

This works fine. However I have two concerns:

  1. With a list of 5000, what kind of impact will this have on performance? I'm planning on using some larger conditionals and then narrowing down (in the example above, I first check for /resources before looking at specific IDs.
  2. While this list will in theory never need to be modified, it feels like an ugly solution both in terms of syntax and logic. Is there a better method I'm not thinking of?
4

1 回答 1

2

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

当您为每个具有“旧内容”的新帖子/页面添加一个字段时,您的代码可能是这样的:

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 的情况下,您检查是否存在重定向并且该查询仅返回一行。

这种方法存在一些问题,即如果有人在两个帖子上输入了相同的数字,则没有办法确定哪个是最重要的重定向。你也可以考虑使用插件来解决这个问题。

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

于 2017-04-04T14:41:56.630 回答