カスタマイズ 2023.09.29 2023.09.29
WordPressでパーマリンク変更後も旧URLでWebページを表示できる仕組み
目次
はじめに
WordPressのパーマリンクは管理画面から簡単に設定が出来るのでとても簡単ですよね。
例えば、パーマリンクをデフォルトの値である記事のIDから投稿記事の名前に変更したい時はパーマリンク設定の”投稿名”をクリックして更新すればすぐに変更が行えます。
このように便利なパーマリンクですが、なぜパーマリンクを変更してもきちんとブラウザに表示されるのでしょうか?
変更した裏側で何が起こっているのか、関連するコードを追っていきながら一緒に理解を深めていきましょう。
(今回はWebサーバーにApacheを使用している前提で進めて行きます。)
パーマリンクの設定
まず、管理画面におけるパーマリンクの設定方法をおさらいの意味も含めて紹介します。
パーマリンクはデフォルトだと”基本”に設定されていますね。
このパーマリンク構造の場合、URLは下の画像のように表示されます。
設定を変更する場合は他の設定にチェックを入れて、”変更を保存”のボタンをクリックすればパーマリンクの変更が出来ます。
URLは下の画像のようにちゃんと変更した値が入っていますね。
これで、無事にパーマリンクの変更が出来ました。
パーマリンクの裏側
次は変更されたURLのリクエストをどのように処理しているのか、ソースコードを追って確認していきましょう。
Apacheについて
ソースコードを確認する前に、今回使用するWebサーバーのApacheについて簡単に説明します。
Apacheは世界で人気のあるWebサーバーソフトです。オープンソースなので、誰でも気軽に使えるところが利点です。
WordPressの公式でもWebサーバーに関する設定でApacheを使用した場合の説明が書かれているため、WordPressにおいても使いやすいWebサーバーの一つだと言えます。
[^1]
リクエストの受け取り
Apacheについて簡単に説明したので、ここからはURLのリクエストがどのテンプレートファイルに割り当てられるのかを、先ほど設定したURLを例にコードを追って見ていきましょう。
今回設定したURL
1 |
http://localhost:8080/2023/09/06/パーマリンクテスト |
以下は、一般的なWordPressにおける「.htaccess」ファイルの記述です。
.htaccessファイルはApacheのコンフィグを編集するために使うファイルです。
.htaccess
1 2 3 4 5 6 7 8 |
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> |
このコードを分解して確認していきましょう。
1 2 3 |
<IfModule mod_rewrite.c> any code </IfModule> |
このコードは
ディレクティブと呼ばれ、Apacheに指定したモジュールが存在していたら中の処理を実行します。
指定の方法は
で指定します。今回はmod_rewriteモジュールがあるかを確認しています。
1 |
RewriteEngine On |
RewriteEngineディレクティブはRewriteモジュールを有効または無効にする処理を行っています。
OnとOffで有効と無効を切り替えることが出来ます。
1 2 3 4 5 |
RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] |
RewriteBaseディレクティブはRewriteRuleディレクティブで使うパスの先頭を指定します。
’/’を指定すると.htaccessファイルが置いてあるディレクトリまでのパスが指定されます。
RewriteRuleディレクティブは正規表現でリクエストのURLに一致するものがあるかを確認し、一致した場合はURLを書き換えてリライト処理が行われます。
正規表現の後には、半角スペースを開けてリライト後のパスを指定します。
2行目では「-(ハイフン)」になっていますが、この場合は書き換えを行いません。
なので、URLは最初と変わりません。
1 |
http://localhost:8080/2023/09/06/パーマリンクテスト |
末尾の大括弧内では、特定の動作や条件を指定するフラグを設定することが出来ます。
例えば、[L]はLastを意味しており、RewriteRuleの処理が行われたら、それ以降の処理を行わない、というフラグです。
RewriteCondディレクティブはRewriteRuleの処理を行うかの条件を指定します。
判定をする値は%{var}で指定します。その後のフラグは判定の条件になります。
3,4行目の%{REQUEST_FILENAME}はURLが入っています。
「!-f」フラグはファイルが存在するかの判定を行っています。
「!」は否定条件を表す演算子なので、この場合はファイルが存在するときは「false」、ファイルが存在しなければ「true」を返します。
「!-d」フラグは-fのディレクトリ版です。
1 |
http://localhost:8080/2023/09/06/パーマリンクテスト |
今回設定したパーマリンクのURLと合致するパスを持つファイルやディレクトリがないので、判定はtrueになります。
5行目のRewriteRuleの正規表現である”.”は全ての文字列にヒットするため、/index.phpにURLが書き換えられます。
書き換えられたので、index.phpにリライトされます。
リライト前
1 2 3 4 5 |
ユーザーに見えてるURL http://localhost:8080/2023/09/06/パーマリンクテスト 実際にリクエストされているURL http://localhost:8080/2023/09/06/パーマリンクテスト |
リライト後
1 2 3 4 5 |
ユーザーに見えてるURL http://localhost:8080/2023/09/06/パーマリンクテスト 実際にリクエストされているURL http://localhost:8080/index.php |
[^2]
リクエストの処理
Apacheの処理によって、パーマリンクで送られたリクエストがindex.phpにリライトされました。ここからはリクエストされたindex.phpの処理を見ていきます。
ソースコードで関連するものを全て紹介するのは膨大な量になるため、直接関係のあるコードを紹介します。
index.php
1 2 |
php require __DIR__ . '/wp-blog-header.php'; |
index.phpはrequireでwp-blog-header.phpを呼び出しています。
wp-blog-header.phpはテンプレートを呼び出すtemplate-loader.phpを読み込む処理があるため、呼び出しが必須なファイルです。
template-loader.phpはこの後紹介します。
wp-blog-header.php
1 2 3 4 5 6 7 8 9 10 11 |
php if ( ! isset( $wp_did_header ) ) { $wp_did_header = true; require_once __DIR__ . '/wp-load.php'; wp(); require_once ABSPATH . WPINC . '/template-loader.php'; } |
wp-blog-header.phpはif文で$wp_did_headerに値が存在するかを見ています。
$wp_did_header変数はif文より前に変数の宣言が行われていませんが、否定演算子の”!”があるのでtrueが返り、以降の処理が実行されます。
if文の処理で重要なのはrequire_onceで呼び出されるwp-load.php、template-loader.phpです。
template-loader.phpの呼び出しに使われている定数はwp-load.phpで定義されています。
他にも、template-loaderで使われる関数はwp-load.phpから呼び出しているものもあるため、wp-load.phpの呼び出しは必須です。
template-loader.phpは最初にリクエストされたパーマリンクのファイルパスを取得して呼び出す処理があるのでこちらも必須です。
今回の場合、
1 |
http://localhost:8080/2023/09/06/パーマリンクテスト |
このパーマリンクのファイルパスを取得しています。
template-loader.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
php if ( wp_using_themes() ) { $tag_templates = array( 'is_embed' => 'get_embed_template', 'is_404' => 'get_404_template', 'is_search' => 'get_search_template', 'is_front_page' => 'get_front_page_template', 'is_home' => 'get_home_template', 'is_privacy_policy' => 'get_privacy_policy_template', 'is_post_type_archive' => 'get_post_type_archive_template', 'is_tax' => 'get_taxonomy_template', 'is_attachment' => 'get_attachment_template', 'is_single' => 'get_single_template', 'is_page' => 'get_page_template', 'is_singular' => 'get_singular_template', 'is_category' => 'get_category_template', 'is_tag' => 'get_tag_template', 'is_author' => 'get_author_template', 'is_date' => 'get_date_template', 'is_archive' => 'get_archive_template', ); $template = false; foreach ( $tag_templates as $tag => $template_getter ) { if ( call_user_func( $tag ) ) { $template = call_user_func( $template_getter ); } if ( $template ) { if ( 'is_attachment' === $tag ) { remove_filter( 'the_content', 'prepend_attachment' ); } break; } } if ( ! $template ) { $template = get_index_template(); } } |
ここではif文の判定にwp_using_themes()関数が使われています。これは現在のリクエストがテーマを使うべきであればtrueを返します。
今回のパーマリンクはテーマ内で使われているので、trueが返ってきます。
$tag_templatesの連想配列はkeyとvalueに関数の名前を定義しています。
foreachでkeyのis_がついた関数をcall_user_func()で呼び出し、その返り値がtrueになるまで回しています。
今回は
1 |
http://localhost:8080/2023/09/06/パーマリンクテスト |
で表示しようしているものがなんのテンプレートなのかを探しています。投稿ページのため、is_singleのタイミングでtrueが返ってきます。
trueが出たら、keyに紐づいたvalueのget_がついた関数(ここでは、get_single_template)を実行して$template変数に入れています。
ここで、
1 |
http://localhost:8080/2023/09/06/パーマリンクテスト |
に合うファイルパスを入手することが出来ました。
template-loader.php
1 2 3 4 5 6 7 8 9 10 |
php if ( $template ) { include $template; } elseif ( current_user_can( 'switch_themes' ) ) { $theme = wp_get_theme(); if ( $theme->errors() ) { wp_die( $theme->errors() ); } } return; |
最後に、if文はtrueで返るため、includeで$template変数に入ったパスが読み込まれます。
これで無事にリクエストした以下のパスが割り当てられました。
1 |
http://localhost:8080/2023/09/06/パーマリンクテスト |
このファイルが実行されることで、ページが表示されます。
まとめ
今回はサーバーのコンフィグ編集とindex.phpから始まる複数のファイルが関係することでパーマリンクの構造を変えてもきちんとリライトされることが分かりました。
皆さんもWordPressの裏側に興味が出てきたらぜひ調べてみて下さい。
参考記事
1. Welcome! – The Apache HTTP Server Project
2. mod_rewrite – Apache HTTP Server Version 2.4
3. wp_using_themes() | Function
4. call_user_func – Manual
※全体参考 パーマリンクの使い方 – サポートフォーラム
WordPressサイト制作・カスタマイズなら「wp.make」にお任せ!
WordPressでのサイト制作やリニューアルを検討する時、以下のようなお悩みはありませんか?
- WordPressに詳しい制作会社に依頼したいが、どこがいいかわからない…
- セキュリティ対策をしっかりしたいが、社内にノウハウがないのでプロに任せたい…
- WordPressに最適なサーバーの選定や構築から依頼したい…
- SEO対策や高速化も考慮したサイト構築を行なってほしい…
- 制作後の保守・運用についてもサポートしてほしい…
- 今のサイトを簡単に運用できるようにしてほしい…
「wp.make」は、WordPressのプロフェッショナル集団によるWordPressサイト制作・カスタマイズサービスです。
サイトの制作だけでなく、WordPressに最適なサーバーの選定や構築といったインフラ面の支援から、SEO対策や表示スピードの高速化、高度なセキュリティ対策や制作後の保守・運用サポートまで、WordPressに関わることならあらゆるお悩みを解消いたします。
既存のお客さまからも
「コミュニケーションが取りやすく、クオリティが高い」
「WordPressのプロとして信頼感がある」
と大変ご好評をいただいています。
WordPressサイトの制作・カスタマイズをご検討されているなら、ぜひ以下からお気軽にご相談ください。
WordPress開発・カスタマイズなら 『wp.make』
全案件WordPressのみ!
株式会社e2eの『wp.make』はWordPress専門のWeb制作サービスです。
WordPress案件だけを扱っているから、技術・ノウハウ・対応力が圧倒的!
【WordPressサイト制作でよくあるお悩み】
・運用シーンが想定されておらず、更新しづらかった…
・打ち合わせで専門用語が多くてわかりづらい…
・制作後の保守には対応してくれなかった…
こんな事態になる前に、ぜひ一度、ご相談ください!
WordPressサイトを作るなら、一番WordPressに詳しいところへ!