PHP Builtin serverで、dot(.)が入るURLで挙動が変わってつらい(かもしれない)
みなさん今日もPHP書いてますか?(挨拶)ここのブログの一番したにAuthorとかかいてあるけど、実際には初めてこのブログに触るuzullaです。
まこぴーさんファンの皆様、もうしわけございません、まこぴー氏多忙につき繰り上げの代替原稿です。
普段は自分のブログに記事かいてるのですが、なんか寄稿しないと気まずいので寄稿します。
私は今日も元気にPHPをかいてます。勿論イヤイヤなどではありません、私はPHPerです!
ところで
来週Perlのお祭りである所のYAPC::Asia Tokyo 2013が開催されますね、最高のイベントです、皆さん行くと思います。 私は前夜祭にて、hachioji.pmの面々と、LTソン::Tinyを開催します
http://ltthon-yapc2013.hachiojipm.org/
先日からトーカーを募集しておりますが、今のところ去年同様に非常にスロースタートな感じで、人があつまらなくて主催の胃がいたいので、YAPC前夜祭に参加する方で、LTしたいかもしれない!という方は是非お待ちしております。
去年同様、飛び込みも(出切る範囲で)受け入れたいと思いますので、一身上や宗教上の理由などでATNDに登録できなくとも、当日は是非宜しくお願い致します。
あ、YAPCはPerlの祭典ですけど、LTソンはPHPでも全然いいですよ。去年もPerlまったく関係ない楽しいトーク沢山ありましたし。なにせ司会がPHPerですから、PHPなら優遇する可能性すらあります。(というか去年、PHPだけは居なかった感)
さて本題もおわりましたので、余談です。
PHP 5.4からはいった、PHPのBuilt-in Server,皆さん活用していることとおもわれます。してますよね? してないし、phpなんか今後も使う気がない、という人はここまでの宣伝もよんでいただけましたでしょうし、有り難うございました、お気を付けてお帰りください。
さて、知らない人に説明すると、DocRootに相当するDirに移動してから
php -S 127.0.0.1:1234
などとすると、Httpdがたちあがって、そのままPHPや、ウェブサイトの開発ができちゃう、というもの凄い便利な憎いやつです。 世の中には「ワンライナーでHTTPを立ち上げて確認」などいうお役立ち情報に注目があつまる事がありますが、PHPならコマンド一発ですよ、まったくすごい。
私も最近はできるだけBSで開発するようになっています、楽なので。 もうApache+mod_phpの環境を何個もならべるのには疲れたのですよ…。
ただ、今現在ちょっとしたところで躓いたので、その話です。 ちなみに、わたし は今php5.5.1で作業をしています。
PHP Builtin Serverの挙動
PHP Builtin serverは、
http://127.0.0.1:1234/hogehoge/test
などしてアクセスしたとき、内部的にindex.phpをよびだすように
/index.php/hogehoge/test
等と変換してくれて、世間一般的に.htaccessとかで設定される感じの、まあ良い感じにしてくれるのですが、
この時、
/hogehoge/pseudo_file_name.html
とかURLにドットがはいると、index.phpに渡されずに、静的ファイルを探しに行ってしまいます。当然404になってつらい
その場合、
php -S 127.0.0.1:1234 index.php
などとして、ルータのPHPファイルを強制指定してあげると良いよ〜というのが定番の解決策です。
でも、これやると全部がPHPの処理になっちゃうから静的ファイルどうするの?不便だ!とおもわれるかもしれません。
大丈夫です、余り細かく説明はしませんが、もし静的ファイルを送りたいときは、return false
でおとすと
再度PHPがファイルをさがしにいってくれるので、ちょっとした追記で心配ご無用の助です(本エントリ後半に、軽いサンプルコードあります)。
http://php.net/manual/pt_BR/features.commandline.webserver.php
しかし…
そういう風に説明はされているんですけど、 .がはいってると、どうも$_SERVERまわりの変数が、.なしとくらべてかわってしまうのですよね、具体的にはPATH_INFOがおかしくなる。
例えば,
<?php
var_dump($_SERVER);
をindex.phpとしておいてある場合に、
http://127.0.0.1:1234/
-出力-
array (size=21)
(略
'REQUEST_URI' => string '/' (length=1)
'REQUEST_METHOD' => string 'GET' (length=3)
'SCRIPT_NAME' => string '/index.php' (length=10)
'SCRIPT_FILENAME' => string '/Users/uzulla/dev/mygreat_app/htdocs/index.php' (length=48)
'PHP_SELF' => string '/index.php' (length=10)
(略
と
http://127.0.0.1:1234/test
-出力-
array (size=22)
(略
'REQUEST_URI' => string '/test' (length=5)
'REQUEST_METHOD' => string 'GET' (length=3)
'SCRIPT_NAME' => string '/index.php' (length=10)
'SCRIPT_FILENAME' => string '/Users/uzulla/dev/mygreat_app/htdocs/index.php' (length=48)
'PATH_INFO' => string '/test' (length=5)
'PHP_SELF' => string '/index.php/test' (length=15)
(略
以上二つは良いのですけれど、ここでtest.php
などとしてみると
http://127.0.0.1:1234/test.php
-出力-
array (size=21)
(略
'REQUEST_URI' => string '/test.php' (length=9)
'REQUEST_METHOD' => string 'GET' (length=3)
'SCRIPT_NAME' => string '/test.php' (length=9)
'SCRIPT_FILENAME' => string '/Users/uzulla/dev/mygreat_app/htdocs/index.php' (length=48)
'PHP_SELF' => string '/test.php' (length=9)
(略
こうなってしまって、/test
と/test.php
で、PATH_INFO
が変わってしまって辛い。
最近のWAFはPATH_INFO
を積極的につかって、routingやargのキャプチャを実現していますが、そいつがコケてしまう…。つらい。
惜しい
まあ、解決策がないわけではなくて、BSの時だけ、処理の前段でPATH_INFOが無い場合にREQUEST_URIを加工して、PATH_INFOをねつ造するというテクもあるのですが、たとえばこういうかんじ。
// Builtin Serverの時だけ処理する、Apacheなどでは無視される
if (php_sapi_name() == 'cli-server') {
// PATH_INFOを捏造
if(!isset($_SERVER['PATH_INFO'])){
$_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI'];
}
// ここで、適切な正規表現で静的ファイルか、PHPへのリクエストかきりわける。
// 静的ファイルならreturn falseさせるように、色々判定させる
if ( !preg_match('#^/(blog|post|nom)/#', $_SERVER["PATH_INFO"])) {
return false;
}
if ( preg_match('#\.(jpg|png|gif|js|css|and_other)$#', $_SERVER["PATH_INFO"])) {
return false;
}
}
// ここから先、通常の処理
var_dump($_SERVER);
まあ、あんまりやりたくないですよね。ここらへん直って欲しいなぁ〜〜。静的ファイルがなかったら、処理するという.htaccessでいうところの
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]
このような挙動をする実装になっていてくれたほうがありがたかった。
PATH_INFOのリカバリが基本になったり、登録されていないrouteならreturn falseしてくれるような感じにWAF側にとりこまれてもいいのですが…。
PHP Builtin serverは開発にとってもイイナイスなものですが、既存環境との差もちらほらあります、これがどう今後埋まっていくのか?という感じですね!
この辺り、もっと良い感じになってくれるといいなーとかおもって今日の話は終わりです。
非常になげやりで、謎な宣伝
友人かつhachioji.pm メンバーのmoznion君(彼女募集中)が承認欲求不満なそうなので、皆さん大変お手数なのですが、ブクマ乞食にブクマをめぐんであげて下さい…。
http://moznion.hatenadiary.com/entry/2013/09/11/163554
ここの所「アイドルに勝ちたい!まけられない!勝たなければセップクしかない!超えられるなら、毛髪をかけてもよい!きえええええ!!!」と大騒ぎしていて、さっさとアイドルのブクマをぬいてもらってmoznion君(彼女募集中)におかれましては精神を安定して頂きたい所です。 参考
今確認したら、あとちょっとでこえられそう、あと一息、あと一息でございます!
一応本文についても触れておくと、マトモなことがかかれています。テック的な話は勿論参考になりますし(俺もはてなインターンで修行したい!と思った、両手で足りないほど遅い)、紋切り型の読書感想文みたいなものではなく、moznion君(彼女募集中)がインターンで得たものを彼なりに説明しているので、良エントリだと思います。moznion君(彼女募集中)の気づきはみなさんにとって既知かもしれませんが、オトク情報だけがネットではありません。
ただ、個人的にいわせてもらえば、ブクマ稼ぎたいならもっと煽ったりネタ画像を貼るべきだった、moznion君(彼女募集中)の実直さ、誠実さが邪魔をしたのでしょう。
そして、LTソンの宣伝をすべきだった。
さておき、「で、誰?」というブクマだけでもよろこばれると思いますので、是非。
http://moznion.hatenadiary.com/entry/2013/09/11/163554
ところで、この写真ボクは変わり兜をかぶった武将にしかみえないんですけど、ボクだけですかね?
さ〜て、明日のHachioji.pm日めくりテックトークは?
東の東(ひがしのあずまさん)さんこと、ytnobodyさんです。
(期待してたまこぴーさんファンは、もうちょ〜っとまっててネ!)