最初の(そして間違った)答え - 以下を参照
次のディレクティブを使用してリダイレクトを実行できます (この順序で)。
RewriteCond %{REQUEST_URI} ^index.php
RewriteRule ^index\.php/(.+)$ /$1 [R,L]
RewriteCond $1 !^(index.php|images|css|js|robots.txt)
RewriteRule ^(.*?)$ /index.php/$1 [L]
これにより、最初に で始まるすべてのリクエストが対応する短縮 URL にリダイレクトされ、次に2 番目のルールがサイレントに処理されます。index.php
index.php/etc
編集 - 読み進めてください!
実際、上記のソリューションでは無限のリダイレクト ループが生成されます。これは、Apache が次のアクションを実行するためです (たとえば、 をリクエストするとします/index.php/abc
)。
- 最初の
RewriteCond
試合
- Apache は [R] をリダイレクトします。つまり、新しい HTTP リクエストを生成します。
/abc
/abc
最初に失敗するRewriteCond
/abc
2 番目に一致RewriteCond
- Apache はリダイレクトしませんが、この URI を
/index.php/abc
. 再びポイント 1 に到達しました。これがループです。
ご注意ください...
- [L] (最後のルール) フラグを使用することで、現在のルールが一致する場合にのみ、これ以上書き換えルールを処理しないように Apache に指示できます。新しい HTTP リクエストが作成されたため、リダイレクトがどのように行われたかについての情報はまだありません。そのため、2 つのうちの 1 つが一致するたびに、新しいリクエストが生成されます (=>ループ)。
- [C] (チェーン ルール) フラグを使用しても意味がありません。これは、前のルールが一致する場合にのみ Apache がルールを処理するようにするためです。一方、2 つのルールは相互に除外されます。
- ルール #1 で [NS] (not if subrequest) フラグを使用することは、単に私たちのケースには当てはまらないため、オプションではありません (これについてはApache RewriteRule のドキュメントを参照してください) 。
- 環境変数を設定することはオプションではありません (残念ながら)。pt 2 で新しい要求が行われるため、設定したすべての環境変数が破棄されます。
/abc
別の解決策は、たとえばに書き直すこと/index.php?path=abc
です。これは、次のルールによって行われます (これらを追加する前に、RedirectMatch 同様のルールを削除してください)。
RedirectMatch ^/index\.php(/.*) $1
RewriteCond %{REQUEST_URI} !^/(index.php|images|css|js|robots.txt|favicon.ico)
RewriteRule ^(.+) /index.php?path=$1 [L,QSA]
CodeIgniter のスクリプトの内部構造はわかりませんが、ほとんどの MVC スクリプトと同様に、$_REQUEST['PATH_INFO']
どのページが要求されているかを理解するために読み取ります。$page
次のように、ページを認識するコードを少し変更できます (ページ パスはvarに格納されていると仮定しました)。
$page = $_REQUEST['PATH_INFO'];
if(isset($_GET['path']) && strlen($_GET['path'])) $page = $_GET['path']; // Add this line
これにより、以前のコードが壊れたり、要求したことが達成されたりすることはありません。