EC2を起動し、sshで接続してvimでphpのxdebugしてみる試み
まずxdebugなんてのは基本的にはvscodeとかと相性がいいわけで何でわざわざvimでやる必要があんねんって話だけど、まあ物事は何事も試しである。
なお、xdebugはversion3から結構変わっている。php7が地味に使えなくなってきてるので、本稿ではphp8が入るシステムを使うよ。具体的にはdebian bookworm まあubuntuでも大体同じようにいくんじゃないかしら。
なお、EC2でささっと設定したのでそのようなタイトルになってるけど、もちろんまっさらじゃなくてもどんなサーバーでも適切に設定すれば動作はします。
サーバーの用意
package upgrade
とりあえず
sudo apt update
を仕掛ける。
admin@ip-172-31-46-247:~$ sudo apt update
Get:1 file:/etc/apt/mirrors/debian.list Mirrorlist [38 B]
Get:2 file:/etc/apt/mirrors/debian-security.list Mirrorlist [47 B]
Reading state information... Done
54 packages can be upgraded. Run 'apt list --upgradable' to see them.
まあこれはapt upgradeしておくにこしたことはないな。
sudo apt upgrade
apache2
nginxでもいいけどやっぱ楽なんで。nginx は次回やります。
sudo apt install libapache2-mod-php
実行結果はこんな感じになった
$ sudo apt install libapache2-mod-php
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
apache2 apache2-bin apache2-data apache2-utils libapache2-mod-php8.2 libapr1 libaprutil1 libaprutil1-dbd-sqlite3
libaprutil1-ldap libgdbm-compat4 libjansson4 liblua5.3-0 libperl5.36 perl perl-modules-5.36 php-common php8.2-cli
php8.2-common php8.2-opcache php8.2-readline ssl-cert
Suggested packages:
apache2-doc apache2-suexec-pristine | apache2-suexec-custom www-browser php-pear perl-doc libterm-readline-gnu-perl
| libterm-readline-perl-perl make libtap-harness-archive-perl
The following NEW packages will be installed:
apache2 apache2-bin apache2-data apache2-utils libapache2-mod-php libapache2-mod-php8.2 libapr1 libaprutil1
libaprutil1-dbd-sqlite3 libaprutil1-ldap libgdbm-compat4 libjansson4 liblua5.3-0 libperl5.36 perl perl-modules-5.36
php-common php8.2-cli php8.2-common php8.2-opcache php8.2-readline ssl-cert
0 upgraded, 22 newly installed, 0 to remove and 0 not upgraded.
Need to get 13.6 MB of archives.
After this operation, 87.1 MB of additional disk space will be used.
Do you want to continue? [Y/n]
つまりここではphp8.2が入っているね。
xdebug
peclでいれてもいいんだけど、debian系ならaptでいれちゃった方が楽よ。ただ最新の機能がどーしても使いたい場合はこの方法じゃだめだけど。
sudo apt install php-xdebug
admin@ip-172-31-46-247:~$ sudo apt install php-xdebug
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
php8.2-xdebug
The following NEW packages will be installed:
php-xdebug php8.2-xdebug
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 559 kB of archives.
After this operation, 1912 kB of additional disk space will be used.
Do you want to continue? [Y/n]
Get:1 file:/etc/apt/mirrors/debian.list Mirrorlist [38 B]
Get:2 https://cdn-aws.deb.debian.org/debian bookworm/main arm64 php8.2-xdebug arm64 3.2.0+3.1.6+2.9.8+2.8.1+2.5.5-3 [554 kB]
Get:3 https://cdn-aws.deb.debian.org/debian bookworm/main arm64 php-xdebug arm64 3.2.0+3.1.6+2.9.8+2.8.1+2.5.5-3 [5264 B]
Fetched 559 kB in 3s (199 kB/s)
Selecting previously unselected package php8.2-xdebug.
(Reading database ... 40927 files and directories currently installed.)
Preparing to unpack .../php8.2-xdebug_3.2.0+3.1.6+2.9.8+2.8.1+2.5.5-3_arm64.deb ...
Unpacking php8.2-xdebug (3.2.0+3.1.6+2.9.8+2.8.1+2.5.5-3) ...
Selecting previously unselected package php-xdebug.
Preparing to unpack .../php-xdebug_3.2.0+3.1.6+2.9.8+2.8.1+2.5.5-3_arm64.deb ...
Unpacking php-xdebug (3.2.0+3.1.6+2.9.8+2.8.1+2.5.5-3) ...
Setting up php8.2-xdebug (3.2.0+3.1.6+2.9.8+2.8.1+2.5.5-3) ...
Setting up php-xdebug (3.2.0+3.1.6+2.9.8+2.8.1+2.5.5-3) ...
Processing triggers for php8.2-cli (8.2.18-1~deb12u1) ...
Processing triggers for libapache2-mod-php8.2 (8.2.18-1~deb12u1) ...
このようにxdebug3.2が入っているのがわかりますね?
sudo service apache2 restart
してapacheを再起動しないとモジュールがwebサーバーに読み込まれなかった。
xdebugの設定を見る
awsの場合のsg設定
もうこの時点でwebサーバーは起動し、phpは動くんだけどAWSの場合セキュリティーグループでポート80を貫通させといてくださいね。
phpinfoを見る
でまあ現状のxdebugの設定は
php -iあるいは上のようなphpinfo()を見るといいんだけど、重要なのは
xdebug.mode
まず、非常に重要な設定としてこの箇所があり、vdebugなどでステップ実行するにあたってはこの設定値はdevelopではなくdebugでないといけない。
/etc/php/8.2/apache2/conf.d/20-xdebug.ini ここ
zend_extension=xdebug.so
xdebug.mode=debug
このようにセットしてrestartする。
xdebug.start_with_request
start_with_requestはとにかく何も考えずtrueにしておく必要がある。(他にtriggerとかあるみたいだけど、今回はとにかく黙ってtrue )
従ってこうなる
zend_extension=xdebug.so
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_hostとclient_port
これはdefaultでlocalhost:9003になっているのでとりあえず変更はしない
vimの用意
$ sudo apt install vim
これはもう入ってるので必要がない。
vimplug
vim用のプラグインマネージャーだ
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
これで導入した。別にpluginマネージャーはvimplugである必要はないが本稿ではこれを利用する。gitもいれておく
sudo apt install git
.vimrcの用意
まあこんなのはchatgptにガバっとやってもらう
" 基本的なVim設定
set nocompatible " Vim特有の操作方法を有効にする
filetype off " ファイルタイプの自動検出を一旦オフにする
set backspace=indent,eol,start " バックスペースキーの挙動をより直感的にする
" ファイルタイプに基づくインデントとプラグインの有効化
filetype plugin indent on
" シンタックスハイライトの有効化
syntax enable
" 自動インデントの有効化
set autoindent
set smartindent
" タブとスペースの設定(PSR-2/PSR-12に準拠)
set tabstop=4 " タブ文字を4スペース幅として表示
set shiftwidth=4 " 自動インデント時のスペース数
set expandtab " タブをスペースに展開
" 検索時の設定
set incsearch " インクリメンタル検索を有効化
set hlsearch " 検索結果をハイライト
" ステータスラインの設定
set laststatus=2 " 常にステータスラインを表示
" ファイルの変更が外部でされた場合、自動的に再読込み
set autoread
" Vimを閉じる際に未保存の変更がある場合、警告を表示
set confirm
" PHP固有の設定
au BufRead,BufNewFile *.php set filetype=php
au FileType php setlocal omnifunc=phpcomplete#CompletePHP
au FileType php setlocal formatoptions+=cro
" シンタックスハイライトのカスタマイズ
if has("autocmd") && exists("+omnifunc")
autocmd FileType php set omnifunc=syntaxcomplete#Complete
endif
" プラグインマネージャーの設定(vim-plugを例とする)
call plug#begin('~/.vim/plugged')
" PHPのシンタックスプラグイン
Plug 'StanAngeloff/php.vim'
" PHPのインデントプラグイン
Plug '2072/PHP-Indenting-for-VIm'
" その他のプラグインをここに追加
" Plug 'その他のプラグイン'
call plug#end()
" プラグインのインストール
" Vimを起動後に :PlugInstall を実行してプラグインをインストール
この後:PlugInstallする
vdebugのinstall
ここではあてvdebugを入れていないので、これを追加し、再度vimを閉じて開いて:PlugInstallする
" プラグインの設定開始
call plug#begin('~/.vim/plugged')
" その他のプラグイン設定...
Plug 'StanAngeloff/php.vim'
Plug '2072/PHP-Indenting-for-VIm'
" Vdebug のインストール
Plug 'vim-vdebug/vdebug'
" プラグインの設定終了
call plug#end()
このようにbeginとendの中に書いておけばok。
さらに
" Vdebug の設定オプション用の辞書を初期化
let g:vdebug_options = {}
" Vdebug が接続を待ち受けるポート番号を設定
let g:vdebug_options['port'] = 9003
" デバッグセッションが終了した時の動作を設定。'stop' はVdebugがデバッグセッションを終了させる
let g:vdebug_options['on_close'] = 'stop'
" Vdebug のウォッチウィンドウの表示スタイルを 'compact' に設定。スペースを節約しつつ情報を表示
let g:vdebug_options['watch_window_style'] = 'compact'
" デバッグセッションが開始されたときに自動的にブレークポイントで停止しないように設定
let g:vdebug_options['break_on_open'] = 0
こんな感じの設定を足しておく。
使ってみる
実はもう十分使える。しかし
admin@ip-172-31-46-247:~$ cd /var/www/html/
admin@ip-172-31-46-247:/var/www/html$ vi test.php
:python3 is not available, vdebug will not be loaded.
Press ENTER or type command to continue
こんな事になる場合はvim-noxが入ってないから
sudo apt instal vim-nox
しておく。
最初のコードスニペット
<?php
// 変数の初期化
$a = 10;
$b = 20;
$c = $a + $b; // ブレークポイント 1: 加算後。期待値: $c = 30
echo "done\n";
これを/var/www/html/test.php に書く。一般ユーザーで書ける権限にしといていいかも。
そしたらbreackpoint設定ラインにカーソルを合わせF10を押す
続いてF5を押すと
connection待受になるので、ブラウザーでtest.phpにアクセスしてみるとグルグル回った状態になっている。この状態でvimのウインドウをactiveにしてみると
ここで$aと$bの内容が表示され$cは表示されていない。ここでF2(Step over)すると
行が進み$cの内容が取得できた。これが「ステップ実行だ」。動作がおわったらF6を2連打すれば抜けられる。この辺のキーは覚えてね。
もうちょい複雑にやってみる。
<?php
// 変数の初期化
$a = 10;
$b = 20;
$c = $a + $b; // ブレークポイント 1: 加算後。期待値: $c = 30
// 条件文を使用
if ($c > 20) {
echo "Sum is greater than 20"; // 期待される出力: "Sum is greater than 20"
} else {
echo "Sum is not greater than 20";
} // ブレークポイント 2: 条件分岐後。期待値: 条件が true であるべき
// 配列の操作
$names = ["Alice", "Bob", "Charlie"];
foreach ($names as $name) {
echo "Name: " . $name . "<br>"; // 期待される出力: "Name: Alice", "Name: Bob", "Name: Charlie"
} // ブレークポイント 3: 各名前の出力後
// 文字列操作
$message = "Hello, world!";
$reversed = strrev($message); // ブレークポイント 4: 文字列反転後。期待値: $reversed = "!dlrow ,olleH"
echo $reversed; // 期待される出力: "!dlrow ,olleH"
echo "done\n";
とし、説明にあるようにブレークポイントを入れていく
実行していってみよう
まずはこれは最初のやつだからStep Overする
ここで止まる。step overするぞ
こっちのブロックに入ったのがわかった。step overする
ここで止まる。step overすると変数に入るぞ
このイテレーションで止まる。Namesに値が入ってるのも注目して欲しい
step overする
ここでイテレーションに入っているのでstep overするごとに$name の値が変化していく。今はCharlieまできたのでstep overするとこのループを抜ける
そしたらここで停止して
$messageにHello, world!が挿入された。そしてstepoverすると
strrev() 関数により「!dlrow ,olleH」となった
ブラウザーにこう表示されて終わる。
このようにstep実行はprintデバッグよりはるかに強力のため、実行環境を用意しておくと便利だ。またvimを使ってサーバー上でシバくのはIDEを用意したくないときとかstagingあるいはtest環境で何となくプロファイリングしたいときとかに結構便利に機能すると思う、少なくともprint debugするよりはね。
また今は関数のdebugをしていないから、全部step overしたけどstep intoってのもある。
次回はこれをdocker環境に持っていくことにする。docker環境だと気をつける事が増えるので、まずネイティブの環境に慣れといた方が楽よ
次回はdocker環境での使い方とトラブルシュートの方法なども含めて同時に行っていこう。
この記事が気に入ったらサポートをしてみませんか?