Я перемещаю сайт, для которого потребуется около 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);
}
}
Это отлично работает. Однако у меня есть две проблемы:
/resources
прежде чем смотреть на конкретные идентификаторы. Ваша проблема в том, что вам нужно будет сделать карту старого контента на новый. Добавление настраиваемого поля для каждого содержимого публикации с эффектом «old_url = 123», а затем выполнение wp_query для post-slug. Я бы предположил, что ваши старые идентификаторы (то есть 123) не обязательно совпадают с новыми. Подход добавления условий для каждого возможного 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 вы проверяете, существует ли перенаправление, и этот запрос возвращает только одну строку.
У этого подхода есть проблемы, а именно, если кто-то вводит, например, одно и то же число в двух сообщениях, нет способа расстановки приоритетов, который является наиболее важным перенаправлением. Вы также можете использовать плагин для решения этой проблемы.
Других решений пока нет …