PHP再入門中の五所です。
FuelPHPでRailsのpry-railsみたいなことをしようとして、それなりに(半日)はまりましたー。
もうvar_dump($hoge);exit;
みたいなことをちまちまやりたくないですからね。
PHPでREPL使いたい
Psy Shell
というRubyのPryやPythonのIPython並のデバッグ力を持つライブラリがあるので、それを使います。
Composerで追加しておいてください。
Composerをまだ使っていない方は、ぜひ下記をご覧ください。
REPL: コマンドラインから1行ずつコマンドを実行できるツール。 スクリプトの実行をやめて、インタラクティブにデバッグできる機能(デバッガ)が付属していることが多い。これ超便利。
Railsのbinding.pryみたいなことがしたい
Railsのbinding.pryは、アプリケーションサーバの実行を中断してデバッグできる便利機能です。
詳細は下記をご覧ください。
これをFuelPHPで再現していきます。
上で紹介したPsy Shell
は、ソースコード中にeval(\Psy\Sh());
とすれば実行を中断してデバッグする機能がありますので、これを利用すればできそうです。
そのためには、ApacheではなくPHP 5.4から追加されたビルトインサーバ機能でPHPを動作させる必要があります。
が、下記で糾弾されているように、ビルトインサーバは機能が不十分です。
PHP :: Bug #61286 :: If the trailing path that follows a script contains a dot PATH_INFO is not set
拡張子のついたURLをルーティングできない
PHPのビルトインサーバ(以下、PHPサーバ)は、拡張子のついたURLをすべて静的ファイルとみなし、かつサーバ変数$_SERVER['PATH_INFO']
をセットしてくれません。
普段ならApacheがセットしてくれるので、何も問題は起きないのですが・・・。
FuelPHPはまず$_SERVER['PATH_INFO']
を見てルーティングしているので、この変数がセットされていないとFuelPHPは静的なファイルを返します。
たとえば、FuelPHPのREST_Controllerを使おうとすると、URLは
http://localhost:3000/user/1.json
みたいになると思いますが、これが404エラーを吐きます。
そこで、
という処理をFuelPHPに渡す前に噛ませることで、無理矢理ルーティングさせます。
ついでに
- FUEL_ENVをセット
- 静的ファイルの場合、処理を中断してファイルを返す
という処理も噛ませちゃいます。
/パス/to/public/router.php
<?php // define environment $_SERVER["FUEL_ENV"] = 'development'; // static files if (preg_match('/\.(?:png|jpg|jpeg|gif|css|js).?[0-9]{0,10}$/', $_SERVER["REQUEST_URI"]) or strpos($_SERVER["REQUEST_URI"], 'assets/fonts')) { return false; } // requests including '.json' if (strpos($_SERVER['REQUEST_URI'], '.json')) { $_SERVER["PATH_INFO"] = preg_replace('/\?.+$/', '', $_SERVER['REQUEST_URI']); } require_once __DIR__.'/index.php';
ビルトインサーバの起動時に、このファイルをエントリポイントに指定します。
cd /path/to/public php -S 0.0.0.0:3000 router.php
ビルトインサーバで稼働できれば、好きなところで
eval(Psy\Sh());
ってやれば、インタラクティブデバッガが起動できますね!!
試しに起動時に何ができるか見てみます。
[k-gosho@localhost] % php -S 0.0.0.0:3000 router.php PHP 5.5.15 Development Server started at Fri Jul 22 09:26:34 2016 Listening on http://0.0.0.0:3000 Document root is /var/www/public Press Ctrl-C to quit. [Fri Jul 22 09:26:36 2016] 172.16.XX.XXX:55234 [200]: /assets/css/style.css?1467956972 [Fri Jul 22 09:26:36 2016] 172.16.XX.XXX:55238 [200]: /assets/js/common.js?1468500094 (~~ 中略 ~~) [Fri Jul 22 09:26:44 2016] 172.16.XX.XXX:55334 [200]: /assets/fonts/fontawesome-webfont.woff?v=4.0.3 (~~ ここで、ソースコード中にeval(Psy\Sh());を挿入してアクセス ~~) Psy Shell v0.7.2 (PHP 5.5.15 — cli-server) by Justin Hileman >>> $_POST => [ "user" => "456", "team" => "", "apply" => "3", "status" => "1", ] >>> $_SERVER => [ "DOCUMENT_ROOT" => "/var/www/public", "REMOTE_ADDR" => "172.16.XX.XXX", "REMOTE_PORT" => "55370", "SERVER_SOFTWARE" => "PHP 5.5.15 Development Server", "SERVER_PROTOCOL" => "HTTP/1.1", "SERVER_NAME" => "0.0.0.0", "SERVER_PORT" => "3000", "REQUEST_URI" => "/progress", "REQUEST_METHOD" => "POST", "SCRIPT_NAME" => "/index.php", "SCRIPT_FILENAME" => "/var/www/public/index.php", "PATH_INFO" => "/progress", "PHP_SELF" => "/index.php/progress", "HTTP_HOST" => "localhost:3000", "HTTP_CONNECTION" => "keep-alive", "HTTP_CONTENT_LENGTH" => "65", "HTTP_CACHE_CONTROL" => "max-age=0", "HTTP_ORIGIN" => "http://localhost:3000", "HTTP_UPGRADE_INSECURE_REQUESTS" => "1", "HTTP_USER_AGENT" => "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/51.0.2704.79 Chrome/51.0.2704.79 Safari/537.36", "HTTP_CONTENT_TYPE" => "application/x-www-form-urlencoded", "HTTP_ACCEPT" => "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "HTTP_REFERER" => "http://localhost:3000/", "HTTP_ACCEPT_ENCODING" => "gzip, deflate", "HTTP_ACCEPT_LANGUAGE" => "en-US,en;q=0.8,ja;q=0.6", "HTTP_COOKIE" => "fuelmid=mEflV......HOckpWr", "REQUEST_TIME_FLOAT" => 1469147215.662, "REQUEST_TIME" => 1469147215, ] >>>
こんな感じで、PHPサーバの実行をやめて、$_POST
や$_SERVER
を確認できました!
もちろん、定義されているすべての変数・クラス・オブジェクトが確認できます。
更にその場でメソッドも実行できるので、デバッグが捗りますね。
変数・メソッド名をタブ補完できるのも楽!
ちなみに、Laravelの場合は、php artisan serve
コマンドが最初からあるので、この手順は必要ありません。Laravelいいなー
rails console
みたいなことがしたい
FuelPHPは、標準のphp oil console
が不便すぎるので、これもPsy Shell
にしちゃいましょう。
下記コマンドでphp oil console
を凌ぐ強力なコンソールが起動できます。
FUEL_ENV=development psysh /path/to/public/index.php Psy Shell v0.7.2 (PHP 5.5.15 — cli) by Justin Hileman HttpNotFoundException with message '' >>>
せっかく立ち上げたので、モデルを生成してみましょう。仮想的なModel_User
クラスを作ります。
(User belongs_to Team
な関係を想定します)
>>> $user = Model_User::find(1) => Model_User {#207} >>> $user->id => "1" >>> $user->name => "Jon" >>> $user->team_id => "1" >>> $user->team->name => "Web service development division"
これでRuby on Railsに負けない開発環境ができましたね!!
ちなみに、Laravelの場合は、php artisan tinker
コマンドが最初からあるので、この手順は必要ありません。Laravelいいなー
おまけ
テストの自動生成? Asset Pipeline?
Laravelならできるのかも。Fuelは無理。