wordpressで404リダイレクト

wordpressではテーマ内に404.phpを入れて置くと、存在しない記事へアクセスがあった時に自動的にこの404ページへ転送されます。しかし、ケースによっては異なるページやステータスコードを返したいこともあるかも知れません。筆者のケースだと、削除したページに対して410を返していたこともありました。

404と410の違い

現在の検索エンジンでは、410も404として扱われているようですが、この仕様は変わることもあるので覚えておいて損はないでしょう。410はgoneとも表記され、記事が永久に消滅したことを意味します。404と似ていますが、こちらは要求された記事が見つからなかったというサーバからの応答です。見つからなかったということなので厳密には永久に削除したという意味ではないと思います。とはいえ、普通は削除という意味に解釈される傾向にあります。

また、一刻も早く検索エンジンのインデックスから削除したいケースにおいて410が使われた時期もありました。しかし、主要な検索エンジンでは専用のウェブアプリケーションをウェブマスターに提供し、そこからインデックス削除を行えるようにしたため、これらを区別する意味があまりなくなったのかも知れません。ただ、一般的なサイトではサーバの初期設定のせいか、ページを削除した場合、404ステータスコードを返すことがほとんどです。

wordpressのリダイレクト

wordpressにはwp_redirectとwp_safe_redirectといった独自関数があります。前者が絶対URL、後者がwp_redirectを利用して安全なローカルへリダイレクトします。

書式は以下の通りです。第一引数にリダイレクト先、第二引数にステータスコードを指定します。第二引数は省略すると初期値の302を返しますので、301としてリダイレクトする場合には注意が必要です。302 は一時的なページ移動を意味し、恒久的な移動を意味する301とは異なります。また、この関数の直後にはexit;を入れて使います。

wp_redirect( $location, $status );
wp_safe_redirect( $location, $status );

wordpressで404リダイレクト

wordpressで404ステータスコードのページへアクセスがあった場合にリダイレクトを行うには、template_redirectアクションフックを使います。このフックはページを表示する直前に処理を行います。

以下は、404へアクセスがあった場合に単純にwordpressのトップページへ転送しています。ステータスコードは初期値の302となります。

add_action( 'template_redirect', function(){
if( is_404() ){
wp_safe_redirect( home_url( '/' ) );
exit();
}
});

ステータスコード404へのアクセスを他のページへリダイレクトさせる時は以下の通り。移動させるため、ステータスコードを301などに変更しないと動作しません。ユーザには優しい結果となりますが、検索エンジンには優しくない結果となります。

上記wordpressの独自関数でも後述するphpのheader関数でも基本的に移動元と移動先で同じ404のステータスコードを吐かせることは出来ないようです。これらの関数で404を指定すると移動は発生せず、存在しないURLに留まったまま404を返します。

add_action( 'template_redirect', function(){
if( is_404() ){
wp_safe_redirect( home_url( '/' ).'not-found.html', 301);
exit();
}
});

PHPでリダイレクト

wordpress上においてPHPの組み込み関数でリダイレクトする場合は、スラッグなどを取得し、条件分岐によって振り分けないと利用できません。header.phpなどのテーマテンプレートは全てのページで読み込まれるため、同じ処理を繰り返すためです。

また、この関数のみをそのまま使うとwordpress上でテンプレートなどを編集できなくなるようです。こういった編集できない現象はwordpressのバージョン4.9から始まりました。コードの記入ミスなどを回避できる反面、wordpressのよく分からない挙動も見受けられます。

header('Location: https://example.com/');
exit;

編集できない場合は以下のように条件分岐を入れることで動作します。下の例では指定URLを配列にしていますので、配列の左側から右側へ転送するという形式で記述していきます。配列の右側とheader関数の第二引数をそれぞれ404用に変更すると、それに対応したページにリダイレクトされ、そのステータスコードを吐いて終了します。

また、上記コードはwordpress以外のphpファイルで動作しますが、以下はワードプレスの独自関数を使っているため、ワードプレスと関係の無い通常のphpファイルでは動作しません。

$url=['https://example.com/1/' => 'https://example.com/2/','https://example.com/3/' => 'https://example.com/4/'];
if(!empty(get_the_permalink()) && array_key_exists(get_the_permalink(),$url)){
foreach($url as $key => $val){
if(get_the_permalink()==$key){
header("Location: ".$val, true, 301);
exit;
}
}
}

他に、phpのheader関数では以下のようにステータスコードを指定することもできます。いずれもexit;を入れて使います。入れないと最後まで読み込まれてしまうためです。

header("HTTP/1.1 301 Moved Permanentl");
header("HTTP/1.0 404 Not Found");
header("HTTP/1.0 500 Internal Server Error");

.htaccessで指定

慣れてくるとワードプレスで設定したほうが早いかも知れませんが、htaccessを使った指定方法もあります。htaccessはApacheと呼ばれているウェブサーバのアプリケーションで利用できるファイルのことです。Nginxと呼ばれるサーバでもこのファイルが共有できるため、多くのウェブサイトでhtaccessが利用できます。ワードプレスではインストール時にもこのファイルに必要なコードを記述します。ちなみにhtaccess名称は慣習的に用いられているだけで、サーバ管理者であればhttpd.confから変更できます。レンタルサーバではほとんどのケースで出来ないと思います。

ErrorDocument 404 /not-found.html

まとめ

リダイレクトする方法はワープレの独自関数を含めいくつかありますが、基本的に一度設定すると変更することは少ないため、htaccessファイルに直接記述して終えることが多いようです。ただ、リダイレクトする量があまりに多い場合はワープレでプラグイン化して管理したほうが楽かも知れません。

また、ワープレは一度保存したスラッグをデータベースに登録する機能も備わっているため、スラッグでURLを構築している場合は何もしなくても新しいURLに転送されるようです。この登録情報はデータベース内のwp_postmetaテーブル内にあります。マルチサイトや接頭辞を変えている場合は、それに対応したテーブル名になっています。