.htaccessを使ってURLから末尾のスラッシュを削除するには?

状況

ドメイン全体では、ファイル拡張子を非表示にする末尾のスラッシュを削除すると、ドメイン名自体とは関係なく(任意のドメインで動作します)

ディレクトリ構造のサンプル

私たちはホームページ以外のインデックス。*ファイルを使用していません。

  • /
    • /index.php
    • /account.php
    • /account
      • /subscriptions.php
    • /login.php
    • /login
      • /reset-password.php

目標

これらのファイルがどのように要求されるか、ブラウザでどのように表示されるかの例をいくつか示します。

  • / and index.php --> mydomain.com (literally just the bare domain name).

  • /account.php or /account/ or /account --> mydomain.com/account

  • /account/subscriptions.php or /account/subscriptions/ or /account/subscriptions --> mydomain.com/account/subscriptions

ご覧のように、各Webページにアクセスするにはいくつかの方法がありますが、どちらの方法を使用しても、ブラウザには1つの優先URLしか表示されません。

質問

mod_rewriteを使用して.htaccessでこれをどのように行うのですか?

私はこれを理解しようと壁に向かって頭を叩きましたが、一般に、書き換えの流れは次のように見えます:

  1. External 301 redirect ( mydomain.com/account/ --> mydomain.com/account )
  2. Internally append .php ( mydomain.com/account --> mydomain.com/account.php )

私は一日中これをグーグルで見つけて、何千ものドキュメンテーションと設定テキストを読んで、何十回も試してみました...私はこれについて多くの頭脳が大いに役立つと思います。

更新

私たちは答えを見つけました(下記参照)。

7
良い質問。彼らは同じことです。 "account"フォルダは "account.php"に書き換えられます。 (この構造はVisual Studio Webプロジェクトでよく見られます)。
追加された 著者 Michael Nielsen,
申し訳ありませんが、私はより明確にすべきでした。私たちはインデックスファイルを使用しません(ホームページは例外ですが、この質問については心配しないでください)。すべてのファイル名は内容を説明しています。例えば、/account//account に書き換え、実際には /account.php i> /account/index.php
追加された 著者 Michael Nielsen,
account.phpとアカウント/フォルダをどうやって区別しますか?それが後続のスラッシュのためのものです。
追加された 著者 tatan,
ハァッ?すみません、それは私には意味がありません。 /account.phpファイルと/account/index.phpファイル(通常は/ account /で簡単にアクセスできます)がある場合、どのように2つのファイルを区別しますか?ファイルシステム上では、それらは同じではありません。 PHPフレームワークのように、単一のindex.phpフォルダを使ってすべてをブートストラップしているのであれば、意味があるかもしれません。それはあなたが意味することですか?
追加された 著者 tatan,

3 答え

質問を見ていただきありがとうございますが、私たちはそれを理解したようです:

Options -Multiviews -Indexes +FollowSymLinks
RewriteEngine On
RewriteBase /
DirectorySlash Off

# remove trailing slash
RewriteRule ^(.*)\/(\?.*)?$ $1$2 [R=301,L]

# rewrite /dir/file?query to /dir/file.php?query
RewriteRule ^([\w\/-]+)(\?.*)?$ $1.php$2 [L,T=application/x-httpd-php]

エンジンが混乱しないように、マルチビューとインデックスを無効にして、代わりに index。* ファイルを参照しようとするか、ディレクトリリストを表示してください(Apacheとは混同して "インデックス" 。)ディレクトリが要求されたように見えるとき。

最初のリダイレクト( R = 301 )は末尾のスラッシュを削除し、2番目のリダイレクトは内部的にPHP(またはHTMLなど)ファイルに書き換えます。

この.htaccessファイルはクエリ文字列もサポートしています。

Update As noted in the comments below much earlier, we've switched to nginx, and this is all our conf file contains related to URL-rewriting (from my dev box):

location =/{
    index index.html;
}

try_files $uri $uri.html =404;

また、PHPから単なるHTMLに切り替えましたが、上記の拡張機能を変更することはほとんど変わりません。

7
追加された
マイナーポイントですが、特別な意味を持たないため、正規表現でスラッシュ(/)をエスケープする必要はありません。 \/は '/'と同じです。
追加された 著者 MrWhite,
後で、私たちはnginxに切り替えました。この全タスクはSUPER-easyでした...
追加された 著者 Michael Nielsen,
@ w3d良い点。それは私のJavascriptの正規表現からの習慣です。
追加された 著者 Michael Nielsen,

あなたのウェブサイトやアプリケーションのURL要求を柔軟かつ簡単にルーティングする方法をご希望の場合は、PHPのマイクロフレームワークをお勧めします。 URLルーティングを完全に制御できるだけでなく、他の利点も提供します。

私は Slim Framework Symfonyテンプレートコンポーネントを使用すると素晴らしい結果が得られます。もし私がもう一度やり直したいのであれば、おそらく Silex Micro-framework を使うだけです。 Symfonyコンポーネントの概要

0
追加された
私たちはこのようなことを考えました(リンクありがとう)が、私たちの開発版はPHPで動いており、デプロイされた本番サイトは100%静的です(PHPはありません)。この.htaccessファイルは、配備された本番サイトの前に置かれます。
追加された 著者 Michael Nielsen,
これらのマイクロフレームワークに基づいて静的なサイトをすばやく作成するのは非常に簡単です。私が使ったプロジェクトは主に静的コンテンツでしたが、マイクロフレームワークを使ってサイトをブートストラップするためにPHPを使うだけでした。サイトのサイズにもよりますが、マイクロフレームワークを使用するように変換することは、一日中.htaccessに対して頭を叩くよりも速いかもしれません。
追加された 著者 tatan,

なぜ/account.phpにリダイレクト/アカウントしたいのですか?実際、ページ/アカウントはコンテンツネゴシエーションにのみ存在します。あなたがそれを望まないなら、ディレクティブを無効にしてください。

あなたの2つのルールについて、私はそれが簡単だと思います:

RewriteRule ^/account/$ /account
RewriteRule ^/account$ /account.php [R,L]

しかし、それはテストされていません。最初の行に [R、L] を追加することもできます。この場合、ブラウザはもう1つリダイレクトします。

0
追加された
理論的には、これは一般的な考え方です(ブラウザに.phpを表示したくないことを除いて)が、account.phpだけで動作します。私たちは、サイト全体で機能する一般的なソリューションを期待しています。 refiddleを使って正規表現をテストすると、regexのような ^(。*)/ $ のURLは末尾にスラッシュがあることを示していますが、サブディレクトリではなく、レベルのディレクトリです。 (サブディレクトリへのリクエストは、完全なサーバーパスをURLに書き換えて何らかの理由でブラウザに表示します)。 ^(。*)[^ /] $ は、末尾にスラッシュのないURL。
追加された 著者 Michael Nielsen,