問題解決
バックエンド, サーバ, Webサーバ

Flying Object lab

飛行物体の実験室 > 記事 > 問題解決 > さくらのレンタルサーバ ライトで".htaccess"を使ったリライトが上手くいかない

さくらのレンタルサーバ ライトで".htaccess"を使ったリライトが上手くいかない

さくらのレンタルサーバ ライトで".htaccess"を使ったリライトが上手くいかない

2025年10月15日

2025年10月16日

 解決策を見たい方は「解決」まで飛ばしてください.

新機能導入に伴う,階層構造の変化

 本サイトはさくらインターネットが提供する「さくらのレンタルサーバ」のライトプランで提供しています.

 直近で記事の記述方式をマークダウンに対応させたのですが,この影響で記事ファイルの読み込み方法が変わりました.

 この記事を含め,私の記事は"/articles"フォルダの直下に配置されています.

 マークダウンに対応する前は,記事をPHPファイルに「直書き」してファイルをアップロードするという非常に面倒なやり方をしていました.

 「直書き」とは,文章を<p>タグで囲み,メタ情報やリンクが現れるたびに<meta>...</meta>や<img src=""></img>を記述し,文章を改行したければ</br>を打ち込んでいたということです.

 これをマークダウンで記述できるようにサイトを変更しました.その方法は,"https://flyingobject-lab.tokyo/articles/article.php?file=2025_10_14"といったような「パラメータ付きURL」を入力したらパラメータを基にマークダウンのファイルが置換され,今までのような形式の記事が表示されるというやり方です.

 (この記事を書くまで,「リライト」と「リダイレクト」の違いが分かっておりませんでした.ここで扱っているのは「リライト」です)

目的: URLをリライトしたい

 記事を書く際,パラメータ付きURLは検索性において問題があると思われます.よって,"https://flyingobject-lab.tokyo/articles/2025_10_14" といった呼び出しが来たら,"https://flyingobject-lab.tokyo/articles/2025_10_14" 以下の内容をファイル名とみなして"https://flyingobject-lab.tokyo/articles/article.php?file=2025_10_14" に変換(リライト)させる.という仕様にさせようと考えました.

ローカルでの動作チェックは通る

 私はローカル環境において一度サイトを整えた後,記事関連ファイルやサイトのプログラムをアップロードしています.現在の環境はXAMPPのv3.3.0です.

 ローカルの.htaccessはhtdocsの直下に配置されており,コードは以下の通りです.

RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_FILENAME}.md -f
RewriteRule ^articles/([a-zA-Z0-9_-]+)$ articles/article.php?file=$1 [L]

RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^articles/([a-zA-Z0-9_-]+)$ articles/$1.php [L]

.htaccessの場所

この状態でXAMPPからApacheを起動します.

XAMPP-Apache

これで"http://localhost/articles/2025_10_14" へアクセスすると

local

問題なく動作しています.

問題: さくらのレンタルサーバー上,リライト処理の不発が起こる

 さくらインターネットの.htaccessによるアクセス制御をしたいというページでは,類似のリライト手法が提示されています.「ライト」プランも対象となっています.

 上記の.htaccessファイルをページの説明通りに配置して,"https://flyingobject-lab.tokyo/articles/2025_10_14" へアクセスすると

404Error

 Not Foundでエラーとなります.

 もちろん,"https://flyingobject-lab.tokyo/articles/article.php?file=2025_10_14" は機能します.

Normal

 この問題は何故起こるのでしょうか.

原因の究明

その1: .htaccessは機能しているか

 まず確認したいのが,".htaccess"ファイルが機能しているかどうかです.

 公開ファイル直下にtest.htmlを配置しておき,ここへアクセスされたらGoogleへリダイレクトする処理を".htaccess"に記述します.

Redirect 301 /test.html https://www.google.com
<p>test file</p>

 これで,"https://flyingobject-lab.tokyo/test.html" にアクセスすると,Googleの画面が開きました.YouTubeのリンクに変えても問題なくリダイレクトが機能しました.

 これで,.htaccessが機能していることは分かりました.

その2: リライト処理の動作チェック(mod_rewriteは通じるか)

 次にリライト処理が動作しているかチェックします.先ほどのtest.htmlへアクセスがあった場合,index.phpへと飛ばす処理を書きます.

RewriteEngine On

RewriteRule ^test\.html$ /index.php [R,L]

 こちらも機能しました.

 では,"https://flyingobject-lab.tokyo/articles/" 以下に何かが記述されたら,article.phpに飛ばす処理を書きます.

RewriteEngine On
RewriteBase /

RewriteRule ^articles/(.+)$ articles/article.php?file=$1 [L]

to_article

 今度はarticle.phpへ飛ばされたようです.

 "https://flyingobject-lab.tokyo/articles/2025_10_14" を試すと

to_article_formatted

 article.phpが呼び出されなくなってしまいました.ちなみに,"https://flyingobject-lab.tokyo/articles/2025-10-14" だとarticle.phpが読み込まれます.

to_article_formatted

 さらに問題を切り分けます.2025_10_14の記事は存在するので,こんどは存在しない記事を読み込もうと"https://flyingobject-lab.tokyo/articles/2025_10_10" を読み込みます.

to_article_formatted_non_exist

 なんと今度はarticle.phpが読み込まれました.2025_10_でも読み込まれることを確認し,前方一致でもなく,「(拡張子を除く)ファイル名が一致する記事が存在する場合にNot Foundが出る」ことが判明しました.(ちなみに2025_10_14.mdを直接指定すると,文字化けしたmdファイルがちゃんと表示されます)

その3. Not Foundエラーの究明

 画面に出てくるNot Foundのファイルは何者でしょうか.どこから出てきたかわからないファイルを使わせないため,以下のように".htaccess"を書きかえます.(リライト処理も一部変更)

RewriteEngine On
RewriteBase /

ErrorDocument 403 /403.php
ErrorDocument 503 /503.php
ErrorDocument 404 /404.php

RewriteRule ^articles/([a-zA-Z0-9_-]+)$ articles/article.php?file=$1 [L]

ErrorDocumentの記述順はこの通りにしないとエラーが起きるとのことです)

 これで,Not Found時に意図したファイルが動くようになりました.

 さて,なぜこのようなことが起こるのでしょうか.

解決

 ここまで,起こったことを記事として起こしながら問題の解明を試みてきましたが,何をすればよいか分からなかったためGoogle Geminiに聞いてみました.

 すると, ApacheのMultiViews(コンテンツネゴシエーション)が問題を起こしている可能性があるとの回答が得られました.

 .htaccessを以下のように書き替え,MultiViewsを無効化します.

Options -MultiViews
RewriteEngine On
RewriteBase /

ErrorDocument 403 /403.php
ErrorDocument 503 /503.php
ErrorDocument 404 /404.php

RewriteRule ^articles/([a-zA-Z0-9_-]+)$ articles/article.php?file=$1 [L]

 これでアクセスしてみます.

動作チェック

 正しく動作しました.

 最後に動作を元に戻してこのような形になりました.

Options -MultiViews
RewriteEngine On
RewriteBase /

ErrorDocument 403 /403.php
ErrorDocument 503 /503.php
ErrorDocument 404 /404.php

RewriteCond %{REQUEST_FILENAME}.md -f
RewriteRule ^articles/([a-zA-Z0-9_-]+)$ articles/article.php?file=$1 [L]

RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^articles/([a-zA-Z0-9_-]+)$ articles/$1.php [L]

 エンジニアの仕事が無くなる不安を増大させる結果となりましたが,なにはともあれ解決しました.

 苦節1日,かなり苦労したので記事として投稿しました.