Apache2.4でMultiViewsを指定してphp拡張子なしでアクセス出来なかった話


ついさっき気付いた事。
Apache2.4ではMultiViewsにしても拡張子無しでPHPにアクセスできないっ。

前段

Apache2.2の頃までは

<IfModule php5_module>
    AddType application/x-httpd-php .php
</IfModule>

<Directory /directory/>
    Options MultiViews
</Directory>

こんな記述をして、
http://domain.tld/sample
と、sample.phpがある場所にアクセスすれば、MultiViewsが動作して sample.php が実行されていたのに・・・。

理由

どうやら、上みたいな感じで安易に使ってしまって sample.bak とか sample.old で退避していたファイルが見えてしまうとか色々問題があったようで、MultiViewsの挙動が変ってしまったもよう。

mod_mime - Apache HTTP サーバ バージョン2.4 から引用

最後に、mod_mime が認識しない拡張子であろうとも、 どんな拡張子でもマッチさせる Any が使用できます。 この挙動は Apache 1.3 のときと同じもので、予期しない動作、例えば .old や .bak ファイルといったウェブマスタが送信を意図していない ファイルを送信する、といった動作を行なう可能性があります。

細かくは、ネゴシエーション順としてContent-Typeから判断したりとか色々高度に処理してくれるみたい。
mod_negotiation - Apache HTTP サーバ バージョン2.4

今回の結論

で、Apache2.4で今回はどうするか、、、。

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php

と、mod_rewriteでお茶を濁すのが手っ取り早かった。。。

他に試したこと

この他にも

RemoveType .php
<Files "*.php">
    MultiviewsMatch Any
</Files>

と、MultiviewMatch のデフォルトが NegotiatedOnly になったから Any を強制してみたり

<IfModule php5_module>
#   AddType application/x-httpd-php .php
    <FilesMatch \.php$>
        Sethandler application/x-httpd-php
    </FilesMatch>
</IfModule>

<Files "*.php">
    MultiviewsMatch Any
</Files>

AddTypeからSetHandlerに変更してみたりしたけど、どれも思った挙動には成らず、404 Not Found を返される状況だった(T_T)
もう少しドキュメントを読み込んで理解すれば、mod_rewriteではない方法でやれるのかもしれないけど、今はこの対処で。。。
(知ってる方いれば、教えてください-。)

2016/12/12 追記

何だか、自分の記事に再度検索で引っ掛かってしまったので修正加筆。

MultiviewsMatch Handlers で動作させることができます。
その場合、

AddType application/x-httpd-php .php
MultiviewsMatch Handlers

Options +MultiViews

という設定になります。
ただ、「AddType」による指定は

Apache が特定の拡張子のファイルを PHP としてパースするよう設定します。 たとえば、Apache が拡張子 .php のファイルを PHP としてパースするようにします。 単に Apache の AddType ディレクティブを使うだけではなく、 悪意を持ってアップロード (あるいは作成) された exploit.php.jpg のようなファイルが PHP として実行されてしまわないようにしたいものです。 この例では、PHP としてパースさせたい任意の拡張子を追加していくだけです。 ためしに .php を追加してみましょう。

Apache 2.x (Unixシステム用)より引用

と言う感じで、PHPのインストールページを見るとAddTypeはお奨めではないようなので、mod_rewriteで対応していた方が気が楽そう。