var_dumpからの卒業、PHP開発を加速するデバッグ手法を考える

# PHPでデバッグ

PHPでのデバッグってみなさん何してます？って聞くと、半分くらいは`var_dump();`か`echo`って返ってくるんです。マジか、とか思うんですけど僕も数年前そうでした。情弱ですね。最近、RailsでWebアプリ作っていると、`binding.pry`が手放せない感じになってきてまして、なんでRails（Ruby）で書くんですか？と聞かれたら、`binding.pry`があるからだと半分くらい本気で思っていて、そんなbinding.pry脳のままPHPの開発にスイッチすると、ちょっとしたことでウガーとなるわけです。JavaやObjective-Cでコード書いている人から見たら、そんなプログラミングのやり方あるのん？と驚かれるわけです。

`var_dump();`を書いてはブラウザ更新して変数の中身を確認したり、メソッドの挙動を確かめるために再度実行したり…そんな苦行からは卒業したい！というわけで、PHPでもRubyのbindig.pry的にデバッグするには…？と模索する趣旨の記事です。

## binding.pryのなにがいいか

実際にbinding.pryをしかけて、デバッグをする様子をアニメーションGIFにしました。分かりにくいですが、Googleログイン後に、pryが起動しています。ブレークポイントをしかけた場所で動作が止まり、そこのスコープでRubyのコードが対話的に書けます。つまり、ブラウザを何回も更新しなくてもいいんです。

![binding.pry.gif](https://qiita-image-store.s3.amazonaws.com/0/2152/be83ad8c-ea3e-a240-5517-be81adb7a20e.gif "binding.pry.gif")

- ブレークポイントをしかけてブラウザでリクエストすると`pry`が立ち上がって対話的にデバッグ可能

どうも思った通りに動かないなーというところに`binding.pry`と書いて、`rails server`でローカルサーバを立ち上げ、ブラウザで叩くと、自動的に対話的なコンソールが立ち上がり、オブジェクトの中身や、メソッドの挙動などを細かくデバッグできます。なにも小難しい設定は必要ない。`Gemfile`に`pry-byebug`と書いて突っ込むだけ。以上。

binding.pryそのものについて、もっと知りたい人は以下の記事がイカしてるのでどうぞ。

- [“binding.pry”って実際のところは何なのだろう](http://qiita.com/yui-knk/items/63a511d243323bec6fb8)

## PsySHでREPLなデバッグ

![PsySH.png](https://qiita-image-store.s3.amazonaws.com/0/2152/c443f0fa-37ab-f3d7-1317-7162d18d9ff1.png "PsySH.png")

で、PHPにも`pry`のようなPsySHというREPL対話式コンソールがあります。導入も簡単で、`wget`で直接もってくるか、`composer`でインストールするだけ。`pry`みたいなノリでいけます。

- [PsySH](http://psysh.org/)

じゃあ、そいつを今手元で動かしているCakePHPやらZendやらsymfony2やらLaravelで動かしたい！となるわけです。どうすればいいか。もう簡単です。`require`して`eval()`でブレークポイント仕掛けたい場所でPsySHを起動するだけ！コード見ろ！見て！

```
<?php
require('./psysh'); // 手動で配置した場合、 composerの場合はautoload使う

function hoge() {
	$name = "piyo";
	
	eval(\Psy\sh()); // ブレークポイント！
	
	return $name;
}
```

もうなんというか、これだけです。

後は、サーバを起動します。サーバに関しては`php-fpm`や`mod_php`ではなくビルトインのサーバを使用します。

```
$ php -S 192.168.33.100:9000
```

ブラウザでアクセスし、ブレークポイントを通過したらPsySHが起動します。そこでゴニョゴニョデバッグできます。ただし、ステップ実行はできません。デバッグしたらexitでリクエストが終了します。ここだけオシイ！それでも実行環境やエディタを問わずデバッグできるので気軽でおすすめです。

## PHPStormでステップ実行

いや…でもステップ実行できないとか、それ本当にPHPの開発加速してやれんの？ってなるんです。というわけで、ステップ実行したいのであれば、IDE的なソフトウェアが必要になってきます。本当はPsySHだけで完結したいけど仕方がない。

Eclipseでもできるっぽいんですが、Eclipseはあんまり好きじゃないのでPHPStormを使います。有償ですが良い感じのソフトです。おすすめ。

### PHP実行環境の設定

デバッグには、定番xdebugを使います。

```
$ sudo yum -y install php-pecl-xdebug
```

```/etc/php.ini
xdebug.remote_enable = On
xdebug.remote_autostart = On
xdebug.remote_host = 192.168.33.1 ;デバッグする環境のIPを指定
xdebug.remote_port="9000"
xdebug.profiler_enable=1
xdebug.profiler_output_dir="/tmp"
xdebug.max_nesting_level=1000
xdebug.idekey = "PHPSTORM"
```

### PHPStormのデバッグ設定

ちょっと、分かりにくいです。

#### PHPデバッグサーバ

PHPStorm→Preferences→Languages&Frameworks→PHP→Serversから、デバッグサーバの設定をします。今回はVagrant環境でやりますが、リモートのテストサーバでも同様なノリでいけます。

![php1.png](https://qiita-image-store.s3.amazonaws.com/0/2152/612f5074-8bc8-348d-864f-25db00f07b5e.png "php1.png")


|項目|値|
|:--|:--|
| Host |PHP実行環境のIPアドレス/ホスト名（今回はVagrantの環境）|
| Port |適宜|
| Debugger |Xdebugを選択|
| Use path mappings |チェックを付けて、PHPStorm側のパスとデバッグサーバ側のパスを合わせます。<br>今回の例だと /Users/zaru/hoge/htdocs と /vagrant/hoge/htdocs みたいな。|

#### デバッグ設定

PHPStorm→Run→Edit configurationsからデバッグの設定をします。

![php2.png](https://qiita-image-store.s3.amazonaws.com/0/2152/d7bbf4c4-416f-8d1c-ef95-384fd03d3e88.png "php2.png")

![php3.png](https://qiita-image-store.s3.amazonaws.com/0/2152/80a43990-dfb8-83a5-4416-25b92897c87b.png "php3.png")

|項目|値|
|:--|:--|
| Configuration |PHP Remote Debug|
| Name |適宜|
| Servers |先ほど作成したサーバを選択|
| Ide key | PHPSTORM |

ここはあまり小難しいことはなく、さっき作ったサーバを選択して「Ide key(session id)」に /etc/php.ini の`xdebug.idekey`で指定したものを入力します。今回の例だと「PHPSTORM」です。

#### デバッガ起動

Run→Debugでデバッガが起動します。そして、Start Listening for PHP Debug Connectionsをクリックします。

![php4.png](https://qiita-image-store.s3.amazonaws.com/0/2152/83a764f7-76ae-3550-38b9-6cf959bf69c0.png "php4.png")

以上で準備が整いました。

#### ブレークポイントを設定

![php5.png](https://qiita-image-store.s3.amazonaws.com/0/2152/efbc278d-af1a-3c14-a206-c4ff5a295fe7.png "php5.png")


設定したいコードの左端をクリックすると赤い丸がつきます。これがブレークポイントです。いざ、ブラウザでアクセス！すると、Debuggerのタブがピコット起動して、変数の中身を見たり、ステップ実行したりできます。非常に強力ですね。Rubyのbinding.pryに比べると、前準備がちょっと大変ですが、一度設定してしまえば気軽に使えるので、良い感じです。

![php6.png](https://qiita-image-store.s3.amazonaws.com/0/2152/f0b971f2-ac90-3660-0cea-e5cec018a528.png "php6.png")

少なくとも`var_dump();`や`echo`、ログ出力などの人力デバッグに比べると、だいぶ開発が加速するような環境になっているかと思います。もっとPHPの開発を加速できるような環境を探し求めて今日もまた旅に出ようと思います。

明日は[@zaru](https://twitter.com/zaru)です！