私は単純なPHPベースのMVC風のフレームワークを書いています。このフレームワークを任意のディレクトリにインストールできるようにしたいです。
私のPHPスクリプトは、リクエストのURIを取得し、それをセグメントに分割します。セグメント1をコントローラー、セグメント2をアクションにします。これを実行すると、これはすべてうまくいきます。
http://www.example.com/mvc/module/test/
それは特定のモジュールコントローラとメソッドに行きます。これで、デフォルトのコントローラ、ホームコントローラができました。これは、フォルダhomeにあります。
このフォルダに直接アクセスすると http://www.example.com/mvc/home/ このフォルダは存在するため、403は禁止されているように表示されます。 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]
あなたの書き換え規則はほとんど問題ないようです。
最初にあなたの.htaccess
ファイルがあなたのドキュメントルート(index.php
と同じ場所)にあることを確かめてください、さもなければそれがその中にあるサブフォルダ(そしてその中のサブフォルダ - 再帰的)だけに影響を与えるでしょう。
次に、ルールを少し変更して、次のようにします。
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]
現時点では、.
に一致しています。これはone任意の文字のインスタンスです。任意の文字の任意の数のインスタンスに一致するには、少なくとも.*
が必要です。
$_GET['path']
変数には偽のディレクトリ構造が含まれるので、例えば/mvc/module/test
をindex.phpで使用してControllerと必要なアクションを決定できます。実行する。
Shebang全体を/mvc/
や/framework/
などのサブディレクトリにインストールする場合は、それを考慮に入れて書き換え規則を少し変更することが最も簡単な方法です。
RewriteRule ^(.*)$ /mvc/index.php?path=$1 [NC,L,QSA]
index.php
ファイルがドキュメントルートにある間、あなたの.htaccess
がそのフォルダにあることを確認してください。
$_GET['path']
の代わりに(18年2月18日および19年1月に更新)
実際にはパスを$_GET
変数として設定する必要はありません。多くのフレームワークは同じ情報を取得するために$_SERVER['REQUEST_URI']
に依存します - 通常どのControllerを使用するかを決定します - しかし原則はまったく同じです。
pathパラメータを作成する必要がないため、これはRewriteRule
をわずかに単純化します(つまり、OPの元のRewriteRule
willを意味します)。今動作します):
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [L,QSA]
ただし、サブディレクトリへのインストールに関する規則は依然として適用されます。
RewriteRule ^.*$ /mvc/index.php [L,QSA]
フラグ:
NC
=大文字と小文字を区別しません(大文字と小文字を区別しません。パターンに文字が含まれていないため、実際には必要ありません)。
L
= Last(このRewriteの後は書き換えを停止しますので、書き換えリストの最後にあることを確認してください)
QSA
= Query String Append最後に?like=penguins
のようなものを持っていて、index.phpに渡したい場合に備えて。
存在しないものすべてをindex.php
にリダイレクトするには、FallBackResource
ディレクティブも使用できます。
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に一致します。
あなたはこのようなものを使うことができます:
RewriteEngine on
RewriteRule ^.+$ /index.php [L]
これはすべての問い合わせをルートディレクトリのindex.phpにリダイレクトします。画像、JavaScriptファイル、スタイルシートなど、存在するファイルに対するクエリもリダイレクトされることに注意してください。
この問題には「トリック」が1つあり、これはすべてのシナリオに当てはまります。 。:)
ここにあります...
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L,QSA]
</IfModule>
基本的に、MOD_REWRITEにURI要求をindex.php
に転送するように要求しています常にファイルが存在する場合 AND 常に要求されたファイルが存在しない場合!
MOD-REWRITEのソースコードを調べて、その仕組みを理解するとき、参照ファイルが存在するかどうかの確認後にすべてのチェックが常に行われることに気付きました。その後のみ、RegEx
が処理されます。 URIがフォルダーを指している場合でも、Apacheはその構成ファイルにリストされているindexファイルのチェックを強制します。
その単純な発見に基づいて、ファイルの存在チェックをダブルタップし、両方の結果を同じエンドポイントにルーティングする限り、すべての可能な呼び出しに十分な単純なファイル検証で十分であることを明らかにしました100%の可能性。
重要:index.php
に "/"がないことに注意してください。デフォルトでは、MOD_REWRITEは、転送用の「ベースフォルダー」として設定されているフォルダーを使用します。それの利点は、サイトの「ルートフォルダ」である必要は必ずしもなく、このソリューションがlocalhost/
および/または適用するサブフォルダで機能することです。
最終的に、以前にテストした他のいくつかのソリューション(正常に動作しているように見えたもの)が、PHP相対パスを介してファイルを「要求」する機能を破りました。注意してください。
一部の人々は、これは洗練されていないソリューションであると言うかもしれません。実際にはそうかもしれませんが、テストに関しては、いくつかのシナリオ、いくつかのサーバー、いくつかの異なるApacheバージョンなどで、このソリューションはすべてのケースで100%動作しました!
愚かな答えがあなたがそれがリダイレクトされていない理由を理解することができない場合は、次のWebフォルダに対して有効になっていることを確認してください..
AllowOverride All
これで、実行しているはずのhtaccessを実行できるようになります。 (代替手段はありますが、問題が発生することはありません https://httpd.Apache.org/docs/2.4/mod/core.html#allowoverride )