質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.36%
mod_rewrite

ApacheウェブサーバーのためのURL書き換えモジュールです。主にプリティーURLに使われていますが、同様に単純置換を超えた、多様なタスクの処理能力や柔軟性があります。

URL

URL(ユニフォームリソースロケータ)とは、インターネット上のリソース(Webページや電子メールの宛先等)を特定するための形式的な記号の並びの事を言う。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

2回答

195閲覧

mod_rewriteでURLのクエリ表記を簡潔にしたい

TTYTT

総合スコア10

mod_rewrite

ApacheウェブサーバーのためのURL書き換えモジュールです。主にプリティーURLに使われていますが、同様に単純置換を超えた、多様なタスクの処理能力や柔軟性があります。

URL

URL(ユニフォームリソースロケータ)とは、インターネット上のリソース(Webページや電子メールの宛先等)を特定するための形式的な記号の並びの事を言う。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2024/08/25 08:56

編集2024/08/25 08:57

実現したいこと

mod_rewriteを使い、URLのクエリパラメータの表記を簡潔にしたい

例)
https://example.com/hoge?id=123 (hogeはphpファイル) にアクセスした際に、
https://example.com/hoge/123 にリダイレクトさせたい

発生している問題・分からないこと

問題点1
~/hoge/123 にアクセスした際に ~/hoge.php?id=123 の内容を表示させることはできたが、
~/hoge?id=123 にアクセスがあった際に ~/hoge/123 へリダイレクトさせることが上手くできない。

これは実際に ~/hoge/123 というファイルが存在していないために実現不可能ということでしょうか。

問題点2
~/hoge?id=123 にアクセスした時と
~/hoge/123 にアクセスした時で、相対パスの位置が変わってしまう

これはどちらからもアクセスできるようにした場合、PHPで相対パスの出力を制御するものなのでしょうか。

また、リダイレクトによって ~/hoge/123 からのアクセスのみに統一できれば問題は起こらないが、
例えばまたパラメータが増えて ~/hoge/123/ABC というURLにしたくなった場合、
hoge.php内の相対パスを全て変更するという対応方法が正しい方法なのか不思議に思っています。

該当のソースコード

<IfModule mod_rewrite.c> RewriteEngine On #拡張子.phpを省略してもアクセス可能にする RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}\.php -f RewriteCond %{REQUEST_URI} !hoge/([0-9a-zA-Z]*)/?$ RewriteRule ^(.*)$ $1\.php [L] #~/hoge/123 にアクセスした際に ~/hoge.php?id=123 の内容を表示させる RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^hoge/([0-9a-zA-Z]+)/?$ hoge.php?id=$1 [L] #~/hoge?id=123 にアクセスした際に ~/hoge/123 にリダイレクトさせる RewriteCond %{QUERY_STRING} (^|&)id=([^&]+)($|&) RewriteRule .* - [E=X_QUERY_ID:%2] RewriteRule ^hoge$ hoge/%{ENV:X_QUERY_ID} [R=301,L] </IfModule>

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

上記のコードの結果は

https://example.com/hoge.php?id=123 アクセス可能だがリダイレクトしない
https://example.com/hoge?id=123 アクセス可能だがリダイレクトしない
https://example.com/hoge/123 アクセス可能だがCSS等の相対パスが無効になる

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

問題点1
これは実際に ~/hoge/123 というファイルが存在していないために実現不可能ということでしょうか。

いいえ。

問題点2
/hoge?id=123 にアクセスした時と
/hoge/123 にアクセスした時で、相対パスの位置が変わってしまう

<img src="xxx.jpg">という記述があった場合、ブラウザは、前者だと/hogeにアクセスしているつもりなので、/xxx.jpgにアクセスに行きます。後者だと/hoge/123にアクセスしているつもりなので、/hoge/xxx.jpgにアクセスに行きます。リクエストするURLのパスをどうするかはブラウザが決めます。

これはどちらからもアクセスできるようにした場合、PHPで相対パスの出力を制御するものなのでしょうか。

これは文章の意味が分かりません。

hoge.php内の相対パスを全て変更するという対応方法が正しい方法なのか不思議に思っています。

これは多分、hoge.phpが返すHTMLのheadに、<base href="/">と書いておく。相対パスの起点が/になるので、どういうアクセスをしようが、/xxx.jpgをアクセスします。

https://example.com/hoge.php?id=123 アクセス可能だがリダイレクトしない

これはリダイレクトする記述が無いので、想定通りですよね?

https://example.com/hoge?id=123 アクセス可能だがリダイレクトしない

これは記述が間違っています。
RewriteRule ^hoge$ /hoge/%{ENV:X_QUERY_ID} [R=301,L]
ですかね。リダイレクト先の先頭に/が必要です。あるいはRewriteBse /を書いておくか、どっちか。

また、301リダイレクトを書いちゃってるので、リダイレクトのテストは .htaccess 修正の度に「ブラウザのキャッシュクリアー」が必要です。
普通はそんなのは面倒なので、テスト中は[R,L]にしておいて、「今後、リダイレクトは絶対に変更しない」という状況になったら、[R=301,L]にします。

上記だと、/hoge/123?id=123にリダイレクトします。/hoge/123が良いなら、
RewriteRule ^hoge$ /hoge/%{ENV:X_QUERY_ID}? [R=301,L]
?を付けるとクエリーを一切付けません。

また、環境変数をセットせず、

Apache

1RewriteCond %{QUERY_STRING} (^|&)id=([^&]+)($|&) 2RewriteRule ^hoge$ /hoge/%2 [R=301,L]

でいいのでは?

クエリーをそのまま残すのでなく、一切付けないのでもなく、
https://example.com/hoge?id=123&x=9&y=10
https://example.com/hoge/123?x=9&y=10にリダイレクトしたい(クエリーからid=だけ除きたい)なら、けっこう面倒。

Apache

1RewriteCond %{QUERY_STRING} ^((?:\w+=\w+)?(?:&\w+=\w+)*)(?:&?id=(\w+))((?:&\w+=\w+)*)$ 2RewriteRule ^hoge$ /hoge/%2?%1%3 [R,L]

か。%1id=より前方の「変数=値」の羅列で、%3が後方のもの。他の意味は正規表現のリファレンス参照。
クエリーの変数と値の文字は簡単のために\wにしてるので変えたければ[]で列挙して下さい。

https://example.com/hoge/123 アクセス可能だがCSS等の相対パスが無効になる

これは、上述の<base href="~~">で対策ですかね。

あと「正規表現を書く場所」「正規表現じゃないものを書く場所」を間違えてます。

投稿2024/08/25 11:38

otn

総合スコア85834

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TTYTT

2024/08/25 15:21 編集

ご丁寧にご回答いただきありがとうございます。 細かい点まで幅広く教えていただき大変勉強になります。 全て噛み砕き理解できたところで早速試してみましたが、うまくいかない点がありました。 #~/hoge?id=123 にアクセスした際に ~/hoge/123 にリダイレクトさせる RewriteCond %{QUERY_STRING} (^|&)id=([^&]+)($|&) RewriteRule ^hoge$ /hoge/%2? [R=301,L] ↑一旦こちらのコードに書き換えてみましたが、 ↓このコードが干渉しているようで、リダイレクトが発生しません。 #拡張子.phpを省略してもアクセス可能にする RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}.php -f RewriteCond %{REQUEST_URI} !hoge/([0-9a-zA-Z]*)/?$ RewriteRule ^(.*)$ $1.php [L] このコードをコメントアウトした時にはリダイレクトが発生し、想定通りの動作になりました。 何かお気付きのことがありましたら、ご教示いただきたく思います。
otn

2024/08/25 16:09

~/hoge?id=123 だと REQUEST_URI は /hoge になるので、 RewriteCond %{REQUEST_URI} !hoge/([0-9a-zA-Z]*)/?$ で除外されると思っていましたが、!hoge/ と / がついてますね。 RewriteCond %{REQUEST_URI} !hoge$ を追加すると除外されます。1つの正規表現にマージしても良いですが。 ところで、 RewriteCond %{REQUEST_URI} !^/hoge/([0-9a-zA-Z]*)/?$ のようにしないのは意図的なんですかね? http://example.com/fugahoge/abc なんかも除外されてしまいますが。 サンプルとしてお書きの ~/hoge のような記述は、https://example.com/hoge のような意味だと思っていますが、もしかして、https://example.com/xxx/yyy/hoge なども含むのですか?
otn

2024/08/25 16:21

もし、~/hoge とクエリー無しの時はリダイレクトせずに ~/hoge.php 扱いするのであれば RewriteCond %{REQUEST_URI} !hoge$ の追加だけだと駄目ですね。もう一つ段落を追加かな。
guest

0

~/hoge?id=123 にアクセスがあった際に ~/hoge/123 へリダイレクトさせる

mod_rewriteでリダイレクトさせるんじゃなく、プログラムの方でリダイレクトさせれば?
__301/308と共に header()を使う

双方向にリダイレクトをしようとすれば、チョッと間違えると無限ループでしょ?
単純にしておいた方が良いと思います。
どうせ開示されているのは質問用のダミーで、本当のモノとは違うのだろうと思います。
それに修正が入った場合など、回答で得たモノを変更しなければならない状況は案外多いのでは?

投稿2024/08/25 15:47

編集2024/08/25 15:51
tezcello

総合スコア326

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問