最近PHPを使っていて、便利だなと思ったライブラリ・ツールを紹介します。
特定のフレームワークに依存しないので、既存のコードに組み込んで利用することもできます。
なお、この記事内のサンプルコードは、カレントディレクトリにComposerがインストールされているのを前提としています。1
実際にコードを書いて試してみたい人は、composer.phar
があるディレクトリで、以下のコマンドを入力して下さい。
mkdir public
php composer.phar init -n
以下のようなファイル・ディレクトリ構成ができたはずです。
├── composer.json
├── composer.phar
└── public
Monolog
「運用中のサービスにバグが見つかったけど、再現方法がわからない」。そんな困った事態にならないよう、Monologで手がかりになる値を残しておきましょう。
Monologはphp composer.phar require monolog/monolog
でインストールできます。
試しに簡単なログ出力をやってみましょう。public/index.php
を以下のように書いてください。
<?php
require '../vendor/autoload.php';
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
// Monologでログを出力してみる
$log = new Logger('cool-php-libraries');
$log->pushHandler(new StreamHandler('../logs/app.log', Logger::DEBUG));
$log->addInfo('トップページの表示');
$log->addError('エラーメッセージ');
$log->addDebug('デバッグ用のメッセージ');
php -S localhost:8080 -t public
でビルトインウェブサーバーを立ち上げた状態で 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、FirefoxならFirePHP2をインストールすると、開発者向けコンソールでMonologのログ出力を表示させることができます。PHPコードの変更は、以下のように、ChromePHPHandler
3、FirePHPHandler
を加えるだけです。
<?php
require '../vendor/autoload.php';
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\ChromePHPHandler;
use Monolog\Handler\FirePHPHandler;
// Monologでログを出力してみる
$log = new Logger('cool-php-libraries');
$log->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なら、文字列ではなくPHPのメソッドでSQL文をつくることができます。
インストールはphp composer.phar require lichtner/fluentpdo:dev-master
でできます。
以下のように、from
、select
、where
、orderBy
といったSQL文と似た名前のメソッドでSQL文を作れます。
<?php
require '../vendor/autoload.php';
$db = '../example.db';
$dsn = 'sqlite:' . $db;
if (!file_exists($db)) {
// データベースの初期化
$pdo = new PDO($dsn);
$sql = <<<EOT
create table record(
id integer primary key autoincrement,
name text,
point integer
);
EOT;
$pdo->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');
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>cool-php-libraries</title>
</head>
<body>
<h1>cool-php-libraries</h1>
<ul>
<?php foreach ($query as $q): ?>
<li><?php echo htmlspecialchars($q['name']); ?> <?php echo htmlspecialchars($q['point']); ?>点</li>
<?php endforeach; ?>
</ul>
</body>
</html>
select(null)
と書いていますが、FluentPDOのselect文はデフォルトではselect *
になるようで、特定のカラムのみ呼び出したい場合は、このコードで一旦デフォルトの設定を無効にする必要があるようです。
デバッグ機能も用意されていて、どんなSQL文が生成されるのかを見ることができます。先に紹介したMonologと組み合わせるなら、こう書きます。
<?php
require '../vendor/autoload.php';
// Monologの初期化処理は省略
$dsn = 'sqlite:../example.db';
$pdo = new PDO($dsn);
$fpdo = new FluentPDO($pdo);
$fpdo->debug = function ($query) use ($log) {
$log->addDebug($query->getQuery());
};
phpdotenv
PHP 5.4以降ではビルトインウェブサーバーという機能があるので、Apacheやnginxをインストールしなくても開発することができるようになりました。
ただ、環境変数をApacheやnginxの設定ファイルに書く前提で設計してしまうと、開発環境でどうするのかという問題が発生します。
そんな時、phpdotenvを使うと、どの環境でも共通の方法で環境変数を参照できるようになります。
インストールはphp composer.phar require vlucas/phpdotenv
でできます。
使い方は、load
というメソッドに.env
ファイルがあるディレクトリを渡すだけです。
<?php
require '../vendor/autoload.php';
// 環境変数の読み込み
Dotenv::load(__DIR__ . '/..');
なお、本番環境でDocumentRootの下に.env
を置くと、当然ブラウザからアクセスできてしまうので、.env
だけ403 Forbiddenになるようにしておくか、DocumentRootの上に置くように設計しておいたほうがいいでしょう。
.env
ファイルは、以下のように変数名と値をイコールで繋いで書きます。
S3_BUCKET=dotenv
SECRET_KEY=souper_seekret_key
必須の環境変数がある場合は、以下のように書いておくと書き忘れにすぐ気づけます。
require '../vendor/autoload.php';
// 環境変数の読み込み
Dotenv::load(__DIR__ . '/..');
// DATABASE_DSNが定義されていないとエラーになる
Dotenv::required('DATABASE_DSN');
2016/07/04追記
FluentPDO公式サイトのURLが変わっていたので変更しました。@kt81 さんご指摘ありがとうございました。
2016/09/13追記
2016/07/04に変更したFluentPDO公式サイトのURLがまた変更されたようです。また変更されたとき修正するのが面倒なので、この記事ではGitHubのURLを貼っておきます。
-
... Composerについて詳しくはこちらを参照してください。http://qiita.com/tadsan/items/a0a14e58aa4d88f19624#composer ↩
-
... ChromePHP=Chrome Loggerの旧名 ↩