お世話になっています。
①http://ドメイン
②http://ドメイン/index/
トップページのみ2つのURLでアクセスできてしまいます。
リダイレクトされません。
(他のページはwwwとindex/がちゃんと消えます)
routes.php
Router::connect('/', array('controller' => 'Index'));
/app/webroot/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{THE_REQUEST} ^.*/index/
RewriteRule ^(.*)index/$ http://www.example.com/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^www\.example\.com
RewriteRule (.*) http://example.com/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
サーバーはロリポップのレンタルサーバーです。
ご存知の方宜しくお願いします。
補足です。
トップページのwwwは消えます。
消えないのは/index/だけです。
.htaccessを使わずに、routes.phpでルートの設定だけで試してみてはいかがでしょう?
あるいは、AppControllerのbeforeFilter()を利用すると、一括で対応できます。
次の記事は、そのままではバージョンの違いと目的の違いにより動作しませんが、使い方の参考になると思います。
http://dxd8.com/archives/4/
※「$this->params['url']['url']」は「$this->request->url」に変更になりました。
http://book.cakephp.org/2.0/ja/appendices/2-0-migration-guide.html
説明不足でしたすいません。
①http://ドメイン
(routes.phpでルーティングされたURL)IndexContrillerのindex()が呼ばれる
②http://ドメイン/index/
(CakePHPコントローラー規約で生成されたURL)IndexContrillerのindex()が呼ばれる
両方のURLで同じページにアクセスできてしまうので、
②のURLでアクセスした場合
①のURLにリダイレクトしてURLをindex/なしに統一したいです。
http://blog.soloweb.jp/noot/server/indexari.html
コントローラ名はIndexControllerで
アクション名がpublic function index() {}です。
routes.phpでアクション名を省略しています。
どこも変更していない場合、「http://~/index/」あるいは「http://~/controller/index/」は、両方とも「index/」なしにリダイレクトされるはずです。
「http://~/index」や「「http://~/controller/index/」がそのままのURLで表示されるのは、末尾にスラッシュ「/」がある場合だけが対象になっているのが原因ですので、該当行を次のように変更するだけで大丈夫です。
RewriteCond %{THE_REQUEST} ^.*/index
RewriteRule ^(.*)index/?$ http://www.example.com/$1 [R=301,L]
#または
RewriteCond %{THE_REQUEST} ^.*/index
RewriteRule ^(.*)index http://www.example.com/$1 [R=301,L]
提示されたhtaccessを両方試してみたのですがうまくいきません。
URLに関して変更はroutes.phpとhtaccessの2ファイルのみです。
routes.php(アクション名index())
Router::connect('/contact/', array('controller' => 'Contact'));
Router::connect('/contact/check/', array('controller' => 'ContactCheck'));
Router::connect('/contact/regi/', array('controller' => 'ContactRegi'));
他のページはどれも
①http://ドメイン/contact/
②http://ドメイン/contact/index/
②でアクセスした際①にリダイレクトされ①のURLに書き換わります。
修正したソース
routes.phpは変更なし
/app/webroot/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
# index統一
RewriteCond %{THE_REQUEST} ^.*/index
RewriteRule ^(.*)index/?$ http://www.example.com/$1 [R=301,L]
# www統一
RewriteCond %{HTTP_HOST} ^www\.example\.com
RewriteRule (.*) http://example.com/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
routes.php
Router::connect('/', array('controller' => 'Index'));
次のようになっていないと、トップページへのアクセスでIndexコントローラは呼ばれないと思います。
routes.php(アクション名index())
Router::connect('/', array('controller' => 'Index'));
Router::connect('/contact/', array('controller' => 'Contact'));
Router::connect('/contact/check/', array('controller' => 'ContactCheck'));
Router::connect('/contact/regi/', array('controller' => 'ContactRegi'));
routes.php
Router::connect('/', array('controller' => 'Index'));
記述してあります。
CakePHPの規約のURLが
http://ドメイン/index/index/
http://ドメイン/コントローラー名/アクション名(省略可)/
だから消えないのでしょうか・・
例えば他ページでは
CakePHPの規約URLなら
http://ドメイン/contact/index/
http://ドメイン/コントローラー名/アクション名(省略可)/
となるのでhtaccessで最後の/index/を省略してくれてリダイレクトされているようにも思います。
こちらでは動作していますから、他に特に変更点がなければ動くはずなのですが・・・
キャッシュやCookieなど全部消したりブラウザを閉じたりして確認しています。
/app/webroot/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
# index統一
RewriteCond %{THE_REQUEST} ^.*/index
RewriteRule ^(.*)index/?$ http://www.example.com/$1 [R=301,L]
# www統一
RewriteCond %{HTTP_HOST} ^www\.example\.com
RewriteRule (.*) http://example.com/$1 [R=301,L]
# 以下はcakePHPデフォルトのまま
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
routes.php(アクション名index())
// Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
// Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
Router::connect('/', array('controller' => 'Index'));
Router::connect('/contact/', array('controller' => 'Contact'));
Router::connect('/contact/check/', array('controller' => 'ContactCheck'));
Router::connect('/contact/regi/', array('controller' => 'ContactRegi'));
/.htaccess
/app/.htaccess
/app/webroot/.htaccess
それぞれ記述ファイルを変えてみたのですがだめでした。
この質問では、CakePHPで作成するサイトのルート(※デフォルトではwebroot)にある.htaccessの記述になります。
トップの「index」が削除されない問題とは関係がありませんが、「index」を削除した時に「www」つきのURLに飛ばすのはリダイレクトを増やすだけなので、この時点で「www」なしのURLにリダイレクトさせた方がいいです。
<IfModule mod_rewrite.c>
RewriteEngine On
# index統一
RewriteCond %{THE_REQUEST} ^.*/index
RewriteRule ^(.*)index/?$ http://example.com/$1 [R=301,L]
# www統一
RewriteCond %{HTTP_HOST} ^www\.example\.com
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
「http://ドメイン/コントローラー名/index」だけでなく「http://ドメイン/index」の場合も、CakePHPのindex.phpに処理が移る前に、.htaccessでindexを削除したURLにリダイレクトします。
index.phpに処理が移ると、「http://ドメイン」の場合、「Router::connect('/', array('controller' => 'index'));」によって、Indexコントローラが実行されます。
※「http://ドメイン/コントローラー名」の場合は、CakePHPの規約によってコントローラ名に該当するコントローラが実行されますので、URLのコントローラ名の部分とCakePHPでのコントローラ名が一致する場合は、ルート設定の記述は必要ありません。
「Router::connect('/contact/', array('controller' => 'Contact'));」は削除しても大丈夫です。
トップのindexが削除されない問題は理由が全然分かりません。
本来なら動作しているはずですので、もう一つ新しく作って試してみてはいかがでしょうか?
大変勉強になりました。
routes.phpで余計な記述は削除していきます。
数々のアドバイス有難う御座いました。