htaccessを使用してすべてをindex.phpにリダイレクトします


131

私は単純なPHPベースのMVC風のフレームワークを書いています。このフレームワークを任意のディレクトリにインストールできるようにしたい。

私のPHPスクリプトはリクエストのURIを取得し、それをセグメントに分割します。これにより、セグメント1がコントローラーになり、セグメント2がアクションになります。これを行うと、これですべてうまくいきます。

http://www.example.com/mvc/module/test/

特定のモジュールコントローラーとメソッドに移動します。これで、デフォルトのコントローラであるhomeコントローラができました。これは、homeフォルダにあります。

このフォルダに直接アクセスすると http://www.example.com/mvc/home/ このフォルダは存在するため、403 forbiddenと表示されますが、代わりにhttp://www.example.comに戻るはずです 。 /mvc/index.php

フレームワークを別のフォルダーにインストールした場合、http://www.example.com/framework/index.phpにリダイレクトする必要があるフォルダーフレームワークとしましょう

すべてのフォルダーとphpファイルをindex.phpにリダイレクトし、その他はすべてそのままにします。

私が最初に遭遇した問題は、それが正しいフォルダにリダイレクトされず、常にドメインルートフォルダにリダイレクトされることでした。

これは私が試したものです:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]

私の質問を正しく理解していることを確認するために:すべての要求をルート index.phpにリダイレクトするか、その特定のフォルダーに 行われたすべての要求をリダイレクトしたいindex.phpですか?
Technoh 2013

htaccessファイルがあるフォルダー、フレームワークのルートディレクトリ。私の例では、mvcディレクトリに戻ります
David Ericsson

回答:


259

書き換えルールはほぼ問題ありません。

まず、.htaccessファイルがドキュメントルート(と同じ場所index.php)にあることを確認してください。そうしないと、ファイルが含まれているサブフォルダー(およびその中のサブフォルダー-再帰的に)にのみ影響します。

次に、ルールを少し変更して、次のようにします。

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]

現時点で、どの文字の1つのインスタンスであるか.を照合しているだけの場合、少なくとも任意の文字の任意の数のインスタンスと一致する必要があります。.*

$_GET['path']変数はそう、偽のディレクトリ構造が含まれています/mvc/module/testあなたが判断するためにはindex.phpで使用できる、例えばコントローラ実行したいとアクションを。


全体のシバンをサブディレクトリにインストールしたい場合、/mvc/または/framework/最も複雑でない方法は、それを考慮に入れるように書き換えルールを少し変更することです。

RewriteRule ^(.*)$ /mvc/index.php?path=$1 [NC,L,QSA]

またindex.php.htaccessファイルがドキュメントルートにある間は、フォルダーにあることを確認してください。


代替$_GET['path'](更新されたFeb '18およびJan '19)

パス$_GET変数として設定する必要は実際にはありません(今では一般的ではありません)。多くのフレームワークは$_SERVER['REQUEST_URI']同じ情報を取得するために依存します-通常どのコントローラーを使用するかを決定するためです-原理はまったく同じです。

パスパラメータRewriteRuleを作成する必要がないので、これはわずかに簡略化されます(つまり、OPのオリジナルが機能するようになります)。RewriteRule

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [L,QSA]

ただし、サブディレクトリへのインストールに関するルールは引き続き適用されます。

RewriteRule ^.*$ /mvc/index.php [L,QSA]



フラグ:

NC =大文字と小文字を区別しない(パターンには文字がないため、大文字と小文字は区別されず、実際には必要ありません)

L =最後(これは、このRewriteの後で書き換えを停止するので、それが書き換えのリストの最後であることを確認してください)

QSA=クエリ文字列の?like=penguins追加。最後に保持してindex.phpに渡したいようなものがある場合に備えて。


1
index.php?path = $ 1
Jacek Pietal、2015

1
あなたはサブディレクトリとしている場合@Proziはないindex.phpをドキュメントルートにある、あなたは必要/リードする-とOptions +Indexesし、index.phpの中に含まDirectoryIndexあなたは可能性がオフのままにindex.phpを完全にだけ使用/?path=$1これは時に当てはまりhttpd-vhosts.conf <Directory>タイプディレクティブではなく.htaccessを介して書き換えを行う。
CD001 2015

これを使用して$ _GET ['path']に依存している場合、nginxサーバーに移動する際に問題が発生します...
barell

3
いいポスト!ユーザーがURL $_GET['path']に追加path=whateverした場合、ユーザーが上書きできることに注意してください。
rybo111 2016

1
@Liviuge-真実ですが、最初はパス全体を渡していた$_GETため、必要だったでしょう(.*)...それはおかしいですが、OPが6年前に使用していたRewriteRuleは、それらに対して機能しませんでした-しかし、MVCアーキテクチャの方法ではPHPで進化した(更新された2月18日のビットに入れたように)それは今では...彼らが時代を先取りしていたと思います:) /mvc/もちろん、ディレクトリへの正しいパスがまだ必要です。
CD001

28

存在しないものすべてをにリダイレクトするにはindex.phpFallBackResourceディレクティブを使用することもできます

FallbackResource /index.php

これはと同じように機能ErrorDocumentします。サーバー上に存在しないパスまたはファイルを要求すると、ディレクティブは暗黙的にへの要求の前置きになりindex.phpます。

すべて(including existant files or folders)をにリダイレクトするindex.php場合は、次のようなものを使用できます。

RewriteEngine on

RewriteRule ^((?!index\.php).+)$ /index.php [L]

無限ループエラーを防ぐために宛先パスを除外した^((?!index\.php).+)$ 場合index.phpを除いて、パターンはすべてのURIに一致することに注意してください。


しかし、あなたはまた、使用する場合があります:DirectoryIndex index.php

1
ルートパス自体もリダイレクトする場合は、パターンの*代わりに使用+します。
Mir-Ismaili、

15

次のようなものを使用できます。

RewriteEngine on
RewriteRule ^.+$ /index.php [L]

これにより、すべてのクエリがルートディレクトリのindex.phpにリダイレクトされます。画像、JavaScriptファイル、スタイルシートなど、存在するファイルのクエリもリダイレクトすることに注意してください。


1
この解決策はほとんど私にとってはうまくいきました。「AH00124:リクエストが10回の内部リダイレクトの制限を超えました」というメッセージが表示され続けました。以前に「RewriteRule ^ index \ .php-[L]」を追加しましたが、完全に機能します!
Fredster、

11

この問題には、すべてのシナリオに当てはまる「トリック」が1つあります。これは、実際に機能していると思わせるために試さなければならない明らかな解決策です... :)

ここにあります...

<IfModule mod_rewrite.c>

   RewriteEngine On

   RewriteCond %{REQUEST_FILENAME}  -f [OR]
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteRule ^(.*)$ index.php [L,QSA]

</IfModule>

基本的に、あなたが求めているMOD_REWRITEをに転送するindex.phpURI要求ファイルが存在する場合は、必ず常に要求されたファイルが存在しない場合

MOD-REWRITEのソースコードを調べてその仕組みを理解したところ、参照されたファイルが存在するかどうかを確認した後、すべてのチェックが常に行われることに気付きました。その後のみRegEx処理されます。URIがフォルダーを指している場合でも、Apacheはその構成ファイルにリストされているインデックスファイルのチェックを強制します。

その単純な発見に基づいて、ファイルの存在チェックをダブルタップして両方の結果を同じエンドポイントにルーティングし、可能性の100%をカバーする限り、単純なファイル検証ですべての可能な呼び出しに十分であることが明らかになりました。

重要:に/」がないことに注意してくださいindex.php。デフォルトでは、MOD_REWRITEは、「ベースフォルダー」として設定されているフォルダーを転送に使用します。それの美しさは、必ずしもサイトの「ルートフォルダー」である必要はなく、このソリューションlocalhost/が適用できる、および/または適用するサブフォルダーがあることです。

最終的に、以前にテストした他のいくつかのソリューション(正常に動作しているように見えたもの)は、PHPの相対パス経由でファイルを「要求」する機能を壊しました。注意してください。

一部の人々は、これは洗練されていない解決策であると言います。実際にはそうかもしれませんが、テストに関しては、いくつかのシナリオ、いくつかのサーバー、いくつかの異なるApacheバージョンなどで、このソリューションはすべてのケースで100%機能しました。


おかげで、これによりFallbackResource index.phpラインがMac(OS X 10.11)で機能するがCentos 7.5では機能しなかったという私の問題は修正されました。ただし、これRewriteRuleにより、たとえばCSSファイルの場所も書き換えられます。PHPファイルのみをリダイレクトする必要があるため、ルールをに変更しましたRewriteRule ^(.*)php$ index.php [L,QSA]。YMMV。
Laryx Decidua

1
お役に立てて嬉しいです。問題は、「htaccessを使用してすべてをindex.phpにリダイレクトする」ため、すべてのファイルを対象としています。PHPファイルのみをリダイレクトする他のより洗練された方法がありますRewriteRule ^(.*)\.php$ index.php [L,NE,QSA]。:今日では、しかし、私はより安価なルールを使用RewriteRule ^.+$ index.php [L,NE,QSA]、条件と組み合わせることができるRewriteCond %{REQUEST_FILENAME} !-fし、RewriteCond %{REQUEST_FILENAME} !-dあるいはして、RewriteCond $1 !^(index\.php|assets|robots\.txt|favicon\.ico)真に特異的であるようにします。
Julio Marchi

5

ばかげた答えですが、リダイレクトされない理由がわからない場合は、以下がWebフォルダーに対して有効になっていることを確認してください。

AllowOverride All

これにより、実行している必要があるhtaccessを実行できるようになります!(代替はありますが、オンにしないと問題が発生しますhttps://httpd.apache.org/docs/2.4/mod/core.html#allowoverride



0

(コアフレームワークフォルダーとファイルの)ディレクトリが存在する場合にすべての要求をフレームワークインデックスハンドラーにリダイレクトする方法をまだ疑問に思っている場合に備えて、いくつかのエラー/成功の試行が.htaccessのRewriteCondを変更する必要があることに気付いたファイル

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

上記の条件は、「ファイルが見つかりません」と「ディレクトリが見つかりません」を示していますが、「見つかりません」(!-d)行を削除して、次のようなもので終わった場合はどうでしょうか。

RewriteEngine on
RewriteBase /framework/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /framework/index.php [L,QSA]

それは魅力のように私のために働いた

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.