こんばんは。滑り込みですが、
この記事はCodeIgniter Advent Calendar 2017の19日目です。
この記事単体でも読めますが、9日目と11日目の続きとしても読める様に書いていきます。
CodeIgniterは基本的なPHPの構文とClassの概念が分かっていれば使い始める事が出来るフレームワークなので、学習コストはかなり低い方だと思います。
初心者でも理解しやすい・触りやすいフレームワークと言えますが、もし初心者の頃から変わらず var_dump();
しまくるプリントデバッグをしているなら、デバッガを使ってみるとより快適な開発が出来ます。
この記事ではDockerを使ってXdebugが動くPHP開発環境を作り、そこでCodeIgniterを動かす事でXdebugの使い方を紹介します。
Dockerで開発環境を作る
docker-composeを使います。開発マシンはMacでDocker for Macを使っている想定です。
docker-composeの設定
docker-compose.yml
は以下の通り。
version: '2'
services:
dev-with-xdebug:
container_name: "codeigniter-xdebug"
image: webdevops/php-apache-dev:ubuntu-16.04
working_dir: /app
volumes:
- ./:/app
- ./custom.ini:/opt/docker/etc/php/php.ini
ports:
- "80:80"
Dockerイメージには、既にXdebugをインストールしたPHPが入っている webdevops/php-apache-dev
を使っています。
イメージの中身が気になる方は GitHubやDocker Hubを見てみて下さい。
このイメージではドキュメントルートが /app
なので、 docker-compose.yml
を置く場所(./
)をコンテナ内の /app
と共有しています。
また、PHPの設定でデフォルトから変える物は custom.ini
に書き出して、Dockerコンテナ内に渡します。
webdevops/php-apache-dev:ubuntu-16.04
のDockerイメージの場合は、PHPが /opt/docker/etc/php/php.ini
という空のINIファイルを読んでいるので、ホスト側の custom.ini
をそこへマウントしています。
Xdebugの設定(.ini)
custom.ini
にXdebugの設定を記述していきます。内容は以下の通り。
xdebug.remote_connect_back = 0
xdebug.remote_host = docker.for.mac.localhost
xdebug.remote_port = 9000
xdebug.remote_handler = "dbgp"
xdebug.remote_autostart = 1
xdebug.remote_log = /app/application/logs/xdebug.log
xdebug.idekey = "docker"
MacでDocker for Macを使っているという想定で xdebug.remote_host = docker.for.mac.localhost
の値を指定していますが、他の環境の場合は適宜変更して下さい。
Dockerコンテナ内から見たホスト側のIPアドレスやホスト名が入るかと思います。
また、ドキュメントルートが /app
なので、そこに置いたCodeIgniterの application/logs/
の中にXdebugのログを書く様に指定しています。
そしてXdebugが9000番ポートを使う様に指定していますが、これは webdevops/php-apache-dev
のDockerイメージの方で穴が開いているので、 docker-compose.yml
の方でEXPOSEの設定を書かなくても大丈夫です。
コンテナ起動
この docker-compose.yml
と custom.ini
を使ってローカル開発環境を建てます。
$ cd ~/Desktop
$ wget https://github.com/bcit-ci/CodeIgniter/archive/3.1.6.zip
$ unzip 3.1.6.zip
$ cd CodeIgniter-3.1.6
$ vim docker-compose.yml
$ vim custom.ini
$ docker-compose up -d
コンテナが起動したか確認
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
505b74f892b9 webdevops/php-apache-dev:ubuntu-16.04 "/entrypoint super..." 39 minutes ago Up 39 minutes 443/tcp, 0.0.0.0:80->80/tcp, 9000/tcp codeigniter-xdebug
$ docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------------------
codeigniter-xdebug /entrypoint supervisord Up 443/tcp, 0.0.0.0:80->80/tcp, 9000/tcp
http://localhost ( http://0.0.0.0:80 )にアクセスすれば、見慣れたCodeIgniterのウェルカムページが出ているハズです。
9000番ポートも穴が空いていますね。
今回はHTTPSで通信しないので、443番は使いません。
エディタの設定
ここまでの設定で、コンテナ内でPHPが実行されるとXdebugが走り、コンテナから見た docker.for.mac.localhost:9000
へ向けて通信をしようとします。
その様子は application/logs/xdebug.log
に書き込まれているハズです。
なので、エディタ側でその通信を受け取ればOKです。
ここからは個々のエディタの設定に依るので省きますが、肝心なのは
- エディタ側から見たら
localhost:9000
(0.0.0.0:9000
) から通信が飛んでくる - idekeyは
docker
- パスのマッピングは
/app
⇔~/Desktop/CodeIgniter-3.1.6
辺りでしょうか。
僕の場合はVimで joonty/vdebug
プラグインを使っているので以下のような設定値になります。
let g:vdebug_options = {
\ "port" : 9000,
\ "debug_file_level" : 2,
\ "debug_file" : '~/.vim/vdebug.log',
\ "ide_key" : 'docker',
\ "path_maps" : {
\ '/app': '/Users/ayato/Desktop/CodeIgniter-3.1.6',
\ },
\}
Xdebugを使う
手順としては
- 解析したい場所のコードにBreakPointを打つ
- エディタでXdebugからの通信を待ち受ける
- PHPを実行させる(ページの再読込みする等)
- BreakPointを打った所でPHPが中断するので、そこで変数の中身を調べたり、その時点での関数の実行結果を確認したりする
といった感じです。
都度 var_dump();
を書くよりも素早く色んな情報を引き出せるので開発スピードが上がるでしょう。
2つ例を出します。
例: application/views/welcome_message.php
こんな感じで85行目にBreakPointを打ちました。この状態で
エディタの方でXdebugからの通信を待ち受けつつ、 http://localhost を開けば解析が始まるハズです。
BreakPointを打った85行目では定数 ENVIRONMENT
によって振る舞いが変わっているので、予想外の振る舞いをした時はこの中身をチェックすると良いでしょう。
慣れるとわざわざ var_dump();
するより圧倒的に楽です。
例: application/controllers/Welcome.php
23行目にBreakPointを打ちました。
ここまで解析を進めた状態でStep inすると、このview関数の中に入って確認する事が出来ます。
application/controllers/Welcome.php
の $this->load->view()
は system/core/Loader.php
で定義される関数 view()
なので、Step inするとそこまでジャンプしていきます。
Step in / Step out / Step over を駆使すれば、おかしな挙動をしている部分を速く見つける事ができるかもしれません。
おわりに
いかがでしょうか?
デバッガは最初は動作の仕組みを勉強する所から初めないといけませんが、慣れればプリントデバッグよりも遥かに速くコードの挙動を調べる事が出来ます。
また、CodeIgniterはコアの部分でも複雑な事はほとんどしていないので、デバッガがあればその挙動を追いかけて勉強する良い教材になると思います。
この記事がデバッガ初心者の方の助けになれば幸いです。