Slim(PHP Framework)事始め(2)

## あらまし

配属先で[Slim](http://www.slimframework.com)を使っているので、使い方などをメモしている。
[前回](http://qiita.com/yookihiroo/items/bfa31644df9676fc6bdb)

### コマンドが動作しない事がある

[前回](http://qiita.com/yookihiroo/items/bfa31644df9676fc6bdb)書き忘れていましたが、

```shell-session
$ composer test
```
等としても動作しない事がありました。
調べてみると、vendor/bin/phpunit辺りの改行コードがCRLFだったりしたのが原因っぽいです

Windows上でVagrantを利用している環境でしたので、gitのautoCRLFが有効になっていた為に切り替え時におかしくなったのかと思います

### [PHP CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer)の導入

composerを導入してあれば

```shell-session
$ composer require --dev squizlabs/php_codesniffer
```
こんな感じで。
余談ですが、インストールしたいライブラリの名前の一部分だけを知っている場合、

```shell-session
$ composer search codesniffer
〜
opus4-repo/codesniffer Coding style for OPUS 4
cakephp/cakephp-codesniffer CakePHP CodeSniffer Standards
escapestudios/symfony2-coding-standard CodeSniffer ruleset for the Symfony2 coding standard
〜
```
こんな感じで検索出来ます
「フレームワーク向けにカスタマイズするのが面倒」などのような時も、例えばcakephp/cakephp-codesnifferなどがあるように、誰かしら作っている可能性があるので、確かめてみるのはおすすめです

とりあえず今回は調べてみてもSlim用の規約があるようでは無いので、こんな感じで設定しました

```json:composer.json
	"scripts": {
        "start": "php -S 0.0.0.0:8080 -t public public/index.php",
        "test": "phpunit",
        "phpcs": "phpcs --standard=PSR2 src/",
        "phpmd": "phpmd src/ text cleancode,codesize,design,unusedcode"
	}
```

### [PHP dotenv](https://github.com/vlucas/phpdotenv)の導入

勉強用にちょっと試しているだけならともかく、大抵の場合は開発環境、ステージング環境、本番環境と設定を分ける必要があるかと思います
そんな時に便利なのが[PHP dotenv](https://github.com/vlucas/phpdotenv)です
このライブラリは、指定したディレクトリにある.envファイルの内容を、環境変数として取り込みます

まずはインストール

```shell-session
$ composer require vlucas/phpdotenv
```

ライブラリ読み込み部分

```php:public/index.php
12 require __DIR__ . '/../vendor/autoload.php';
13
14 // find environment file
15 $dot_env = __DIR__. '/../.env';
16 if (is_readable($dot_env)) {
17     $dotenv = new Dotenv\Dotenv(__DIR__. '/../');
18     $dotenv->load();
19 }
20
21 session_start();
```

試しにDEBUGという変数と、エラー表示をセットしてみる

```bash:.env
DEBUG=1
DISPLAY_ERROR=1
```

設定で使用

```php:src/settings.php
01 <?php
02 return [
03     'settings' => [
04         'debug' => getenv('DEBUG'),
05         'displayErrorDetails' => getenv('DISPLAY_ERROR'), // set to false in production
...
```

他、プロジェクトをクローンしてきた時に「どのような環境変数を設定するのか？」が分からなくなりがちなので、_envというファイルでも作っておいて、各々作業に入る前に.envにコピーして〜というルールを決めておくといいかと思います

```bash:_env
# for production environment
DEBUG=0
DISPLAY_ERROR=0
```

```bash:.gitignore
/.env
```

### [whoops!](https://filp.github.io/whoops/)導入
whoops!は、「シマッタ！」みたいな意味でしょうか？
とりあえず、このライブラリでは「シマッタ！」時のエラー表示を詳しくしてくれます

今回試してみた感じだと、フレームワーク側でob_startしている箇所があり、それが原因なのかうまく表示出来ないケースがあったので、Slim用のwhoopsを導入してみます

```shell-session
$ composer require --dev dopesong/slim-whoops
```

```php:src/dependencies.php
04 $container = $app->getContainer();
05
06 // 上の.envでDEBUG=1の時にデバッグ機能をオンにする
07 if ($container->get('settings')['debug']) {
08    // ob_start前のエラーをハンドルする
09    $whoops = new Whoops\Run;
10    $whoops->pushHandler(new Whoops\Handler\PrettyPageHandler);
11    $whoops->register();
12    // ob_start以降のエラーをハンドルする
13    $container['phpErrorHandler'] = $container['errorHandler'] = function($c) {
14        return new Dopesong\Slim\Error\Whoops($c->get('settings')['displayErrorDetails']);
15    };
16 }
```

### デバッグバーの導入

デバッグバーは、フルスタックのフレームワークではよく見かけるのですが、実行時間や環境変数などの情報やエラーなど、本来サーバ側のログを見ないと分からないような情報をブラウザ側で表示してくれるツールです

[PHP用で有名なもの](http://phpdebugbar.com)の他に、それぞれのフレームワーク用実装があるのですが、今回は[こちら](https://github.com/kitchenu/Slim-DebugBar)をインストールしてみます

```shell-session
$ composer require --debug kitchenu/slim-debugbar
```

```php:src/dependencies.php
12    // ob_start以降のエラーをハンドルする
13    $container['phpErrorHandler']/* = $container['errorHandler']*/ = function($c) {
14        return new Dopesong\Slim\Error\Whoops($c->get('settings')['displayErrorDetails']);
15    };
16
17    // debugbar setting
18    $settings = $container->get('settings')['debugbar'];
19    $provider = new Kitchenu\Debugbar\ServiceProvider($settings);
20    $provider->register($app);
21 }
```
今回、$container['errorHandler']をコメントアウトしているのは、デバッグバーの方でslimのexceptionを読み込むようになっているのですが、そのエラーがwhoopsの方で処理しようとしてエラーが起こる為です

```php:src/settings.php
01 <?php
02 return [
03     'settings' => [
04         'debug' => getenv('DEBUG'),
06         // debug bar
07         'debugbar' => [
08             'storage' => [
09                 'enabled' => true,
10                 'path' => __DIR__. '/../logs/debug/',
11             ],
12         ],
...
```
この設定をしておくと、過去のリクエストの情報を保存しておいて、デバッグバーの方から参照出来るようになります
OAuthのライブラリなどでは、ライブラリ内でリダイレクトをするようなものもあり、それに気づかないでいると「あれ？どうしてこんな動作するんだ？」という事になりますが、そのような挙動も記録しておいてくれるので便利です

### 感想
色々と便利なライブラリがあるので、導入すると便利に開発していけるかと思いますが、ひとつひとつ検証していくのは相当骨が折れます。。。
やはりフルスタックのフレームワークは便利ですね

後はORMで手頃なライブラリがあればいいかと思うのですが、doctrineだと大げさな気はしますし、他の小さなライブラリなんかはサポートなんかが不安で難しいところです