--- title: コード改善に役立ちそうなPHPライブラリ・ツール tags: PHP:5.4 monolog FluentPDO phpdotenv author: ryu22e slide: false --- 最近PHPを使っていて、便利だなと思ったライブラリ・ツールを紹介します。 特定のフレームワークに依存しないので、既存のコードに組み込んで利用することもできます。 なお、この記事内のサンプルコードは、カレントディレクトリに[Composer](https://getcomposer.org/)がインストールされているのを前提としています。[^1] 実際にコードを書いて試してみたい人は、`composer.phar`があるディレクトリで、以下のコマンドを入力して下さい。 ```text mkdir public php composer.phar init -n ``` 以下のようなファイル・ディレクトリ構成ができたはずです。 ```text ├── composer.json ├── composer.phar └── public ``` ## Monolog 「運用中のサービスにバグが見つかったけど、再現方法がわからない」。そんな困った事態にならないよう、[Monolog](https://github.com/Seldaek/monolog)で手がかりになる値を残しておきましょう。 Monologは`php composer.phar require monolog/monolog` でインストールできます。 試しに簡単なログ出力をやってみましょう。`public/index.php`を以下のように書いてください。 ```php:index.php pushHandler(new StreamHandler('../logs/app.log', Logger::DEBUG)); $log->addInfo('トップページの表示'); $log->addError('エラーメッセージ'); $log->addDebug('デバッグ用のメッセージ'); ``` `php -S localhost:8080 -t public`で[ビルトインウェブサーバー](http://php.net/manual/ja/features.commandline.webserver.php)を立ち上げた状態で http://localhost:8080/ にアクセスしてください。`logs/app.log`に「トップページの表示」、「エラーメッセージ」、 「デバッグ用のメッセージ」というメッセージが出力されているはずです。 `pushHandler`メソッドに渡した`StreamHandler`がログの出力先を表すHandlerクラスです。これを書き換えることで出力先をファイルにしたり、メールで送ったり、DBに登録したりと、色々変更することができます(複数指定することもできます)。 `StreamHandler`の第二引数に指定しているのがログの出力レベルです。Monologでは、レベルの低い順に以下が規定されています。 * DEBUG * INFO * NOTICE * WARNING * ERROR * CRITICAL * ALERT * EMERGENCY ログ出力に使っている`addほにゃらら`メソッドの`ほにゃらら`は上記のレベル名で、Handlerクラスで指定したレベル未満のメソッドは、たとえ書いてあってもどこにも出力されません。 例えば、上のコード例では`StreamHandler`に`Logger::DEBUG`を指定しているので、すべてのレベルのログが`logs/app.log`に出力されますが、`Logger::INFO`に変更すれば、`addDebug`メソッドの内容は出力されなくなります。 つまり、Handlerクラスに指定するログの出力レベルを環境によって変更できるようにしておけば、簡単に出力する/しないを切り替えることができます。 ## Chrome Logger & FirePHP Chrome or Firefoxなら、`echo`を使うよりスマートなやり方でデバッグできます。 Chromeなら[Chrome Logger](http://craig.is/writing/chrome-logger)、Firefoxなら[FirePHP](https://addons.mozilla.org/ja/firefox/addon/firephp/)[^2]をインストールすると、開発者向けコンソールでMonologのログ出力を表示させることができます。PHPコードの変更は、以下のように、`ChromePHPHandler` [^3]、`FirePHPHandler`を加えるだけです。 ```php:index.php pushHandler(new StreamHandler('../logs/app.log', Logger::DEBUG)); $log->pushHandler(new ChromePHPHandler(Logger::DEBUG)); $log->pushHandler(new FirePHPHandler(Logger::DEBUG)); $log->addInfo('トップページの表示'); $log->addError('エラーメッセージ'); $log->addDebug('デバッグ用のメッセージ'); ``` ただ、FirePHPは、私の環境(Mac 10.9.5、Firefox 35.0.1、FirePHP 0.7.4、Firebug 2.0.8)では日本語のログが文字化けしました。日本語のログは出力しないようにした方が無難かもしれません。 ## FluentPDO ユーザーの入力値によって文字列でSQL文を作る仕様のコードを書いたら、リリース後に条件によってSQLが構文エラーになるバグが見つかった、なんてことありませんか? [FluentPDO](https://github.com/envms/fluentpdo)なら、文字列ではなくPHPのメソッドでSQL文をつくることができます。 インストールは`php composer.phar require lichtner/fluentpdo:dev-master`でできます。 以下のように、`from`、`select`、`where`、`orderBy`といったSQL文と似た名前のメソッドでSQL文を作れます。 ```html+php:index.php query($sql); $fpdo = new FluentPDO($pdo); $values = [ ['name' =>'山田太郎', 'point' => 500], ['name' =>'山田花子', 'point' => 300], ['name' =>'鈴木一郎', 'point' => 890], ['name' =>'山本五郎', 'point' => 90], ]; foreach ($values as $value) { $fpdo->insertInto('record', $value)->execute(); } } else { $pdo = new PDO($dsn); $fpdo = new FluentPDO($pdo); } $query = $fpdo-> from('record')-> select(null)-> select('name')-> select('point')-> where('point > ?', 100)-> orderBy('point DESC'); ?> cool-php-libraries

cool-php-libraries

``` `select(null)`と書いていますが、FluentPDOのselect文はデフォルトでは`select *`になるようで、特定のカラムのみ呼び出したい場合は、このコードで一旦デフォルトの設定を無効にする必要があるようです。 デバッグ機能も用意されていて、どんなSQL文が生成されるのかを見ることができます。先に紹介したMonologと組み合わせるなら、こう書きます。 ```php:index.php debug = function ($query) use ($log) { $log->addDebug($query->getQuery()); }; ``` ## phpdotenv PHP 5.4以降では[ビルトインウェブサーバー](http://php.net/manual/ja/features.commandline.webserver.php)という機能があるので、Apacheやnginxをインストールしなくても開発することができるようになりました。 ただ、環境変数をApacheやnginxの設定ファイルに書く前提で設計してしまうと、開発環境でどうするのかという問題が発生します。 そんな時、[phpdotenv](https://github.com/vlucas/phpdotenv)を使うと、どの環境でも共通の方法で環境変数を参照できるようになります。 インストールは`php composer.phar require vlucas/phpdotenv`でできます。 使い方は、`load`というメソッドに`.env`ファイルがあるディレクトリを渡すだけです。 ```php:index.php