1. haruna-nagayoshi

    No comment

    haruna-nagayoshi
Changes in body
Source | HTML | Preview

今月からXdebugを使い始めて、分かったことや分からないままのことをまとめました。

※設定については、Dockerを利用している前提で説明します。
PhpStormの機能については、PhpStormでステップ実行するならどんな環境でも参考になると思います。
(InteliJについて書かれた記事も参考にしたので、JetBrainsのIDEを利用しているなら大体同じかもしれません)

Dockerについて

この一連の記事が分かりやすいので参考にしてください。
【Docker Compose】設定内容を1行ずつ理解しながらLaravel環境構築(PHP-FPM、Nginx、MySQL、Redis)
※とくに参考にした3番目の記事のみを貼っています。
※分かりやすいので広まってほしい。

ステップ実行ができる状態にするまでの設定

動作確認環境

(なにを記載すれば十分なのかわからないので自分の実行環境を書けるだけ書いておきます)

Windows10 Pro
Laravel 5.5
Docker Desktop 2.1.0.1
Docker 19.03.1
Nginx 1.12.2 (dockerコンテナ上でnginxが動作)
PHP 7.2 (dockerコンテナ上でphp-fpmが動作)
PhpStorm 2019.2.1
xdebug 2.7.2 (php-fpmコンテナにインストールする)

XdebugをDockerコンテナにインストール

Xdebugをインストールするためのコマンドを、Dockerfileに記載します。

Dockerfile

RUN pecl install xdebug \
   && docker-php-ext-enable xdebug

xdebugをPHPで有効にする

php.iniにxdebugを有効にするための値を記載します。

php.ini

xdebug.idekey="PHPSTORM"  // 識別しやすい値ならなんでもOK
xdebug.remote_enable = On
xdebug.remote_autostart = On
xdebug.remote_connect_back = Off
xdebug.remote_host = "host.docker.internal"
xdebug.remote_port=9001  // 何番ポートでもOK

xdebug.idekeyxdebug.remote_portは、後述するPhpStorm側の設定で利用するだけなので、好きなkeyやポート番号を使います。

他の項目が何を設定しているかについては、この記事を参考にしてください。
[PHP] Xdebug のリモートデバッグ、理解していますか?

xdebug.idekeyや`xdebug.remote_portをPreferencesで設定せずともXdebugを使えるらしいです。再現できず、正確な方法が分からなかったため今回はxdebug.idekey等を設定する方法で説明します。

PHPアプリ開発をPhpStormでスムーズに始められるよう、設定ファイルとドキュメントを用意する

PHPアプリリポジトリに docker-compose.yml を用意しておけば、Preferences を開いて設定しなくても、PhpStormでデバッグできました。

Dockerコンテナを起動する

Dockerfilephp.iniを記述したら、Dockerコンテナを起動します。

$ docker-compose up -d 

これで、Xdebugが有効になった環境が整いました。

PhpStormの設定

次に、PhpStormでステップ実行を行うための設定をします。
ここからは画像で説明していくので、 Ctrl + Alt + S で設定画面を開いてください。
まず、先ほどphp.iniに記載したポート番号を入力します。
デフォルトの9000でもよいのですが、メモ PHP docker xdebugによると、

なんでかXdebugがデフォルトで使うport:9000と、php-fpmがデフォルトで使うport:9000とが、被っているので、どちらかを変える必要がある

そうなので、9001を指定しています。
ポート番号が他のプロジェクトやツールと被らなければ、恐らく何でもいいと思います。
image.png

Serversの設定では、
①Name, Host, Port, Debuggerを設定します。
Name, Host は識別のための名前なのでどんな名前でもOKです。
Portには先ほど設定した9001、
Debuggerには、今回使うXdebugをセットしておきます。

②Use path mappingsにチェックを入れます。

③File/Directoryにはローカルのパスが書いてあり、
Absolute path on serverには対応するDockerコンテナ側のパスを書きます。
docker-compose.ymlでマウントさせているパスが対応づけられていれば大丈夫だと思います。
image.png

ツールバーのこの部分から、Edit Configuration...をクリック。
image.png

Run/Debug Configurations ウィンドウが開かれます。
+マークをクリックしてPHP Remote Debugを選択します。
image.png

新規の設定ファイルが作成されます。

①Nameには適当な名前を入力、
②Serverには先ほど任意の名前をつけたServerを選択、
③IDE keyにはphp.iniで記入した値を入力します。
image.png

完成した設定ファイルをセットしたら、

the Debug button のアイコンをクリックして the Active Debugger icon の状態にします。
image.png

デバッグしたい処理の任意のコードにブレイクポイントを設定します。(x行目を表す数字の右側をクリックでON/OFFできる)
ブラウザでLaravelのアプリケーションを動かし、実際にその処理を走らせると、
Incoming Connection from Xdebugというウィンドウが表示されるので、Acceptボタンをクリックします。
image.png

すると、ブレイクポイントを設定した時点でプログラムが中断され、ステップ実行することができます。
Debugウィンドウには、スタックトレース、リクエストで渡された値が表示されます。
image.png

参考

メモ PHP docker xdebug
PHPアプリ開発をPhpStormでスムーズに始められるよう、設定ファイルとドキュメントを用意する

PhpStormの機能

ステップ実行をすると、ソースの深い部分まで簡単に追うことができます。
Laravelやその他ライブラリの深い部分まで読むと、理解が深まったり、バグ解決の助けになります。

基本

ステップ実行では、StepIntoやStepOutボタンを押しながらソースを追ったり、式の評価をすることができます。
PhpStormでステップ実行するときの基本的な使い方について、分かったことを説明します。
Step〇〇の違いについては、実際に使うのが一番理解が早いと思います。(例になるコードを書く気力がなかった...)

Step Over (F8)

image.png
現在の行から1つ先の行に移動する。
現在の行で関数が呼び出されていても、その関数を呼び出さずに次の行に移動する。

Step Into (F7)

image.png
現在の行から1つ先の行に移動する。
現在の行で関数が呼び出されている場合、その関数の中に進む。

Force Step Into (Alt + Shift + F7)

image.png
Step Intoはコンストラクタ関数や、ClassLoader.phpなどのどうでもいいところをスキップする仕組みがあるのに対し、
Force Step Into の場合は、この設定を無視してスキップせずに全て実行出来る。つまり、Step Intoよりも細かく見れる。

設定画面のこの部分で追加できるらしいですが、まだまともに設定したことがないので割愛。
デフォルトだと何も設定されておらず、その場合はStep IntoForce Step Into は同じ挙動...?
image.png

Step Out (Shift + F8)

image.png
現在の関数の1つ外まで移動する。
Step Intoで関数のなかに入ったあとStep Outすると、関数の呼び出し元に戻ることができる。

Run to Cursor (Alt + F9)

image.png
カーソルが置いてある行まで実行し、カーソルが置いてある行で停止する。
Vimのプラグインを入れている場合、恐らくインサートモード状態でないとカーソルとして認識してくれない模様。なのであまり使っていない。

Evaluate Expression (Alt + F8)

image.png
デバッグ中に「ここで別のメソッド呼ぶとどうなるんだろう」と思ったら、
Evaluate Expressionボタンで、コードを動的実行した結果を見ることができる。
改めてコードを記述して再度ステップ実行を開始する必要はない。

Evaluate Expressionボタンを押すとウィンドウが開かれる。
image.png
Expression: に評価したい式を入力し、Evaluateボタンを押すと、Result:に結果が表示される。
Expression: では入力補完が効いていて、インスタンスから呼び出せるメソッドやPHPの標準関数が補完される。
画像の例では、使いこなせていない私が適当にEvaluateしたのでerrorで怒られています。

Resume Program (F9)

image.png
中断していたプログラムを再開する。
さらにブレイクポイントを設定している場合は、そこで再度中断する。
ブレイクポイントからブレイクポイントへ飛べるイメージ。

デバッグ中に変数の中身を書き換える

DebugウィンドウのVariablesタブに表示された変数を右クリック→Set Variable
で変数の値を書き換えられます。
image.png

デバッグ中に開かれたファイルを閉じたくない

ファイルをいくつも開いた状態で新たにファイルを開くと、最初に開いていたファイルが勝手に閉じられます。
ファイルのタブを右クリック→Pin Tab すると、勝手に閉じないようになります。(自分で閉じた場合は通常通り閉じます)
Pin Tab はデバッグに限らずいつでも使えます。

ステップ実行でプログラムを進めていくと該当ファイルが次々と開かれますが、
「このファイル、後で読み直したい!」というときはPin Tab しておけば、あとで読み返せます。

↓Container.phpにピン留めのマークがついています。
image.png

参考

式の評価
PhpStormのデバッグを使いこなす
IntelliJ IDEAのデバッガのstep over, step into, force step into, step out, drop frame, run to cursor 機能の解説
AndroidStudioで覚えておくべきデバッグTIPS

他にも機能がたくさんあるけど調べきれない

使っていてわかったら書くかもしれない・・・。

blade.phpでブレイクポイントを使う方法

デフォルトだと、blade.phpでブレイクポイントを設定しても、デバッグできません。
image.png
コードとして xdebug_break();を記述することで、ブレイクポイントの代用とするそうです。

Laravel5.7までは、コンパイル済みのbladeテンプレートのほうを参照するらしい。
PhpStormの公式Laravel News で説明されている通り、Laravel5.8からはblade.phpに直接ブレイクポイントを設定できるとのこと。
image.png

ブレイクポイントの違い

公式の説明によると、ブレイクポイントには3種類あるらしい。

JavaScriptもデバッグできる

難しいjs書かないし、ブラウザの開発者ツールで十分なことが多いので需要はなさそう。
Node.jsならNode.js、Vue.jsならVue.jsのためのデバッグツールが存在するんだとしたらそれらを使うほうがいいのかも。

虫単体のマークと、虫+電話のマークの違い

全然わからない。
the Debug button the Active Debugger icon は「the Debug button」「the Active Debugger icon」
start listening php debug connections stop listening php debug connectionsは「start listening php debug connections」「stop listening php debug connections」と呼ぶらしい。
PhpStormによるデバッグ: 基本ガイドPHP CLIスクリプトのデバッグを深く読めばわかるのかもしれない。

今まで the Active Debugger iconstop listening php debug connections両方をONにした状態でデバッグしていたが、

記事を書くために改めて調べているうち、 the Debug button だけでデバッグ作動することに気づいた。

ブラウザの拡張機能を使うときに、受信デバッグマークをListen状態にしておくのかも。

ゼロコンフィギュレーションデバッグ

公式ガイドに頻繁にでてくる。名前から察するに、「細かい設定いらずでデバッグできる」という意味?
PhpStormによるデバッグ: 基本ガイド
公式だけでもこれだけ方法が書いてあるし、Qiitaなど個人の記事にもいろんなパターンがある。
今回の記事で説明した設定手順がベターかどうかもわからない。

Xdebugでテストコードを分析

Xdebugによるプロファイリング
テストコードをほぼ書いたことがないのでどんな機能かはわからない。

jquery-cropperで求めた座標・幅・高さの値をもとに、Intervention Imageで画像をトリミングする実装をしていて、それと同時にXdebugを使い始めました。
dd()var_dump()を書く必要がないので、Intervention Imageの中身や自分が書いたコードをデバッグするのがとても楽で感動しました。
デバッグめんどうくさい...というひとは、ぜひXdebugで楽をしてほしいです。