
【PHP×Apache】.htaccessでクリーンURLを実現する方法
投稿日: 2025-07-12 | カテゴリ: 開発今回は、PHPサイトでありがちなview_article.php?file=◯◯のような野暮ったいURLを、
.htaccessを使って クリーンなURL(/view_articles/◯◯)に変換する方法を解説します。
これは「URLリライト」と呼ばれるテクニックで、SEOの観点からも重要です。
クエリパラメータ付きのURLよりも、シンプルで階層的なURLの方がインデックスされやすく、
ユーザーにも分かりやすいため、Apacheで運用しているサイトではほぼ必須の設定といえます
.htaccessとは?
.htaccessは、Apache系サーバーで動くWebサイトの挙動を細かく制御できる設定ファイルです。
URLの見た目と実際の処理を分けるURLリライトなどによく使われます。
たとえば、こんなURL:
https://example.com/view_articles/20250706_excel_tips
にアクセスしたときに、実際には以下のPHPファイルが処理を担当するように裏でつなぎます: view_article.php?file=20250706_excel_tips
何も考えずにphpでwebサイトを構築すると、URLに重複(クエリあり・なし)を生んでしまいSEO的に評価が分散します。 そのため、SEO的にまずいことになるので修正はマストです。
実際の.htaccessの書き方
以下のように.htaccessを編集します:
RewriteEngine On
# 既存のルールを保持
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
# view_articles/スラッグ を view_article.php に渡す
RewriteRule ^view_articles/([^/]+)$ /view_article.php?file=$1 [L,QSA]
では次に各行について説明します。
RewriteEngine On
.
まずこれは、Apache上でURL書き換えを有効にします。
この行がないと、以降のRewriteRule
やRewriteCond
は無視されます。
RewriteCond %{REQUEST_FILENAME} !-f
アクセスされたURLが既存のファイルではない場合のみ、リライトルールを適用します。
CondはConditionですね。
たとえば、https://<自分のドメイン>/img/logo.png
のように、
実在する画像ファイルにアクセスされた場合は、そのままファイルを返します。
実際の運用では、静的ファイル(画像、CSS、JSなど)は適切なディレクトリにまとめて配置し、
アクセス制御(例えばBasic認証やディレクトリ制限)などを別途設定するのが一般的ですが、
それは本記事の本題ではないのでここでは割愛します。
RewriteCond %{REQUEST_FILENAME} !-d
アクセスされたURLがサーバー上に実在するディレクトリではない場合、リライトルールを適用します。
例えば、https://<自分のドメイン>/admin/というディレクトリが実際に存在しており、その前提でhttps://<自分のドメイン>/admin/にアクセスされた場合は、
リライトは発動しなくて良いということです。
なぜこの2つの条件が必要なのか
これらの条件がないと、たとえ https://<自分のドメイン>/css/style.css
のように実際に存在するCSSファイルがあったとしても、
Apacheがそれを「存在しない」と判断し、下の RewriteRule
が発動して、
本来読み込むはずだったファイルではなく view_article.php
に内部的に転送されてしまいます。
つまり、CSSが読み込まれない、画像が表示されない、といった深刻なバグが発生します。
RewriteRule ^view_articles/([^/]+)$ /view_article.php?file=$1 [L,QSA]
ここがリダイレクト処理の本体です。
- ^view_articles/([^/]+)$ /view_articles/ に続く「スラッグ」(文字列)をキャプチャします。
- /view_article.php?file=$1 そのスラッグを file パラメータとしてPHPに渡します。
文末の [L, QSA]
は、それぞれ次の意味です:
L
(Last):このルールが適用されたら、以降の RewriteRule を無視します(これが最後のルールであることを示す)。QSA
(Query String Append):元のURLにクエリパラメータ(例:?mode=edit
)が含まれていた場合、
書き換え先のURLにもそのクエリ文字列を 追記する ようにします。
たとえば、/view_articles/seo?mode=edit
にアクセスしたとします。
- [L, QSA]なし:
view_article.php?file=seo
- [L, QSA]あり:
view_article.php?file=seo&mode=edit
これがないと、もとのパラメータが消えてしまい、正しく動作しないケースが多発します。
関連知識
htaccessはどのタイミングで起動するのか
ユーザがサイトにアクセスした際、ApacheはまずリクエストURLを受け取り、.htaccessのルールを順次適用して処理方法を判断します。
リライトとリダイレクトの違いについて
リライトとは、ユーザーがブラウザのアドレスバーに入力したURLはそのままに、サーバー側で裏の処理対象を別のファイルやスクリプトに内部的に切り替える仕組みです。 つまり、ブラウザのURLは変わらず、サーバー内部だけで処理が書き換わるので、ユーザーは気づきません。 例えば、/view_articles/seo という見た目の良いURLを入力しても、実際にはサーバーは view_article.php?file=seo に処理を回している、というイメージです。
一方、リダイレクトは、サーバーがブラウザに対して「別のURLへ移動してね」と指示を出し、ブラウザがその新しいURLに切り替わる仕組みです。 この場合、ブラウザのアドレスバーに表示されるURLも変わります。 例えば、古いページのURL /old-page にアクセスすると、サーバーから新しいURL /new-page に移動するよう指示されて、ブラウザが実際にその新しいURLに遷移します。
まとめると、リライトは「見た目のURLはそのままで、裏側だけ処理を変える」技術で、リダイレクトは「ブラウザのURLを別の場所に書き換えてページを移動させる」技術です。 用途や目的によって使い分ける必要があります。
項目 | リライト(Rewrite) | リダイレクト(Redirect) |
---|---|---|
動作場所 | サーバー内部 | ブラウザ(クライアント側) |
ブラウザURL | 変わらない | 変わる |
ユーザー体験 | URLはそのままで処理内容だけ変わる | URLが変わり、ページが遷移する |
主な用途 | クリーンURLの実現、内部ルーティング | ページの移転通知、URLの統一 |
まとめ
大学1年生の時のレンタルサーバを借りてブログを立ち上げたことがありました。 その際も、htaccessを編集した記憶がありますが、当時は何も理解せずに、なんかのwebサイトを見ながら修正した気がします。
当時に比べたら格段に成長しているのかなと思います。