【PHP】ローカル環境でオペコード（phpdbg・vld）を表示する

# はじめに

ローカル環境でオペコードを表示したときの覚書です。
私のように「文字入力して指示するの？」「黒い画面？」「なにそれ怖い」という超初心者の方にとって、オペコードを表示するのは少し敷居が高いと思います。
そのような方の参考になれば幸いです。

私の環境は下記の通りです。

|OS|XAMPP|Apache|PHP|
|:--|:--|:--|:--|
|Windows10|5.6.24|2.4.23|5.6.24|

この記事では、オペコード自体に対する説明はありません。
オペコードについて詳しく知りたい方は下記が参考になると思います。
この記事の対象者には（私にとっては）レベルが高くて難解ですが、詳説です。

+ [PHP による hello world 入門 | 東北ギーク](http://tech.respect-pal.jp/php-helloworld/)

オペコードを表示する方法は、2つあります。

一つ目は、`phpdbg` で確認する方法です。
PHP5.6以降をお使いなら、何もせずにオペコードを表示できます。
ただ、表示されるオペコードが少し見づらいです。

もう一つがPECLとして提供されている  [Vulcan Logic Disassembler（vld）](https://pecl.php.net/package/vld) という拡張ライブラリを使って確認する方法です。
PHPマニュアルやWikipediaなどで「拡張モジュール、拡張ライブラリ、拡張パッケージ」と表記が揺れますが、ここでは同義として扱い、拡張ライブラリと表記します。（というか私がそれぞれの違いを説明できないです（´ω｀；））

この記事の対象者ならPECLて何？って方がほとんどだと思いますが、下記のWikipediaの[説明](https://ja.wikipedia.org/wiki/PECL)がわかりやすいです。

> PECL（ピクル、PHP Extension Community Library）は、PHPで利用できる拡張ライブラリ（パッケージ）を提供しているサービス。

> PECLで提供されるライブラリはCで記述されているため、PHPで記述されたPEARのライブラリよりも高速に動作する。PECLにより提供されるライブラリはPHPの拡張モジュールとしてインストールされる。一方で、PEARライブラリはPHPのバージョンアップに伴う再インストールが原則として不要なのに対し、PECL拡張モジュールはPHP内部のAPIに依存する部分があるため、PHPのバージョンアップに伴いAPIが変更された場合は再コンパイルを必要とする。

> PECLのインストール用には、PEAR同様に「pecl」コマンドが提供されている。インストール方法もほぼPEARと同じだが、インストール後に設定ファイル（php.ini）の「extension」でインストールしたモジュールを指定する必要がある点が異なる。なおWindows版では、手動でphp.iniを修正して、あらかじめコンパイル済みのPECL DLLを組み込むのが一般的な方法である。

ここで覚えておくことは、PHPで利用できるモジュールは、PECLとPEARという2つあるということ、PECLはC言語で記述されており、PHPのバージョンアップに伴い、新しいバージョンに対応した拡張モジュールに変更する必要があるということです。
また、PECLの拡張モジュールをインストールするときは、`php.ini` の記述を変更する必要があるということです。

今回使うvldというライブラリは、これだけインストールすれば動作します。
使うライブラリによっては、○○ライブラリを使うのに△△ライブラリが必要ということがあります。
○○ライブラリと△△ライブラリを2つインストールする必要があり、手間です。
ライブラリ管理ツールと呼ばれる [Composer（コンポーザー）](https://getcomposer.org/)というのを使うと関連するライブラリを自動でインストールしてくれます。
非常に便利です。
これからPHPやるぞって方は、Composerについても抑えておくと役立つと思います。
ただ、関数やクラスの基本的な書き方を覚えたぞっていう段階の方は、すぐにComposerについて覚える必要はないと思います。
ライブラリ使いたい、CakePHPなどのフレームワークを使いたいというタイミングで覚えれば良いかと思います。
偉そうに言ってますが、私もComposerを2・3回しか使ったことありません（´ω｀；）
ここでは、Composerというのが存在しますという説明のみですので、興味のある方は調べてみてください。

それでは、オペコードを表示する方法を見ていきましょう。
XAMPPはインストール済みとします。

# phpdbgを利用する方法

PHP5.6以降ならphpdbgでオペコードを表示できます。
仮に `C > xampp > htdocs > a.php` にある `a.php` のオペコードを表示するとします。
`a.php`は下記のように記述しています。

```php:PHP（a.php）
<?php
echo 'Hello';
```


管理者権限でコマンドプロンプトを開きます。
おそらくコマンドプロンプトの初期値ではCドライブのユーザーフォルダにいるかと思います。
`a.php` がある `xampp` の `htdocs` のディレクトリに移動するために下記のように記述します。

```
> cd \
> cd xampp\htdocs
```

これで、`htdocs` のディレクトリに移動しました。
下記のように記述してphpdbgを使ってオペコードを表示します。

```
> phpdbg
> exec a.php
> print exec
```

下記のようにオペコードが表示されます。

![phpdbg.jpg](https://qiita-image-store.s3.amazonaws.com/0/72985/c9262cd8-fe84-5e33-6f19-17c01b2cf095.jpeg)

`C0`や`C1`は定数を表しており、`info literal`を叩くと値が表示されます。

phpdbgには様々なコマンドがあり [phpdbg 簡易マニュアル · GitHub](https://gist.github.com/hotta/8246028005595bf08662) が参考になります。

phpdbgを終了したいときは `q` を入力すると終了します。

次は、vldを利用する方法を見ていきましょう。

# vldを利用する方法

Macなら @syossan27 さんが書いた下記の方法で、vldを利用できるようになるかと思います。

+ [Qiita - 初心者PHPerがオペコードをvldを使って覗いてみた](http://qiita.com/syossan27/items/056572f22236c971669a) by @syossan27 さん

Windowsだと少し異なるところはありますが、 @syossan27 さんの記事を参考にオペコードを表示することができました。
ありがとうございます((_ _ (´ω｀ )ﾍﾟｺ
Windowsへのインストールする方法が異なるということは、PHPマニュアルにも[書いて](http://php.net/manual/ja/install.pecl.windows.php)あります。
Windowsの場合ですが、下記の4つのステップでvldライブラリを追加できます。

1. vld のデータをダウンロードする
1. ダウンロードしたファイルを拡張ライブラリのディレクトリに設置する
1. `php.ini` に記述を追加する
1. オペコードの表示

手順さえわかれば、簡単です。
順を追って見ていきましょう。

## 1．vld の拡張ライブラリのデータをダウンロードする

vld の[ダウンロード先](https://pecl.php.net/package/vld)へアクセスします。
vld-0.12.0.tgz (16.2kB)  の横にあるウインドウズマークのDLLを選択します。

![vld1.jpg](https://qiita-image-store.s3.amazonaws.com/0/72985/40e58e81-0879-eb27-18c9-54c33ee499e2.jpeg)

先ほど、PECLについて下記のように説明しました。

> PHPのバージョンアップに伴い、新しいバージョンに対応した拡張モジュールに変更する必要があるということです。

PHPのバージョンによって異なるため、下記のようにバージョンごとにダウンロードするファイルが異なります。

![vld2.jpg](https://qiita-image-store.s3.amazonaws.com/0/72985/fdf8453b-adc9-b3e5-e9e2-fc8d751764e9.jpeg)


私は PHP5.6 を使っておりますので、PHP5.6の DLL List から選択します。
DLL List には4つあります。
x86 は32bit版のWindowsで、x64 は64bit版のWindowsです。
他に Non Thread Safe（ノンスレッドセーフ）  と Thread Safe（スレッドセーフ）  があります。
これは、PHPをモジュール版として動作させているのか、CGI版として動作させているかによって異なります。
モジュール版として動作させている場合は、Thread Safe を選択します。
CGI版として動作させている場合は、Non Thread Safe を選択します。
XAMPPの初期設定なら、モジュール版として動作していると思いますので、Thread Safe を選択すれば良いかと思います。
モジュール版かCGI版かは、`phpinfo()`で確認できます。
`Server API` の項目で `Apache 2.0 Handler` が表示されていれば、モジュール版です。
`Server API` の項目が `CGI/FastCGI` が表示されていれば、CGI版です。

![phpinfo1.jpg](https://qiita-image-store.s3.amazonaws.com/0/72985/666f0ae8-48d8-f88c-c03e-86bdd3fdbc76.jpeg)

お使いの環境にあわせて、ダウンロードしてください。

## 2．ダウンロードしたファイルを拡張ライブラリのディレクトリに設置する

ダウンロードしたzipファイルを解凍するといくつかファイルがありますが、 `php_vld.dll` のみ使用します。
`php_vld.dll` を拡張ライブラリのディレクトリに設置します。
XAMPPを使用している方なら `xampp > php > ext` の中に `php_vld.dll` を設置します。
拡張ライブラリのディレクトリは、`phpinfo()` で確認できます。
`extension_dir` の項目にディレクトリのパスが記述されておりますので、拡張モジュールのディレクトリが不明な方は `phpinfo()` で確認してください。

![phpinfo2.jpg](https://qiita-image-store.s3.amazonaws.com/0/72985/a7527aee-155c-3bff-e542-d2048baec3d1.jpeg)

## 3．php.ini に記述を追加する

`php.ini` テキストエディタで開きます。
XAMPPの環境なら、`php.ini`のファイルは `xampp > php > php.ini` にあります。
`php.ini` に下記を追記します。

```
extension=php_vld.dll
```

## 4．オペコードの表示

オペコードを表示するには、コマンドプロンプトを使用します。
phpdbgのときと同様に `a.php` のオペコードを表示します。
`a.php`がある`htdocs`のディレクトリまで移動したと仮定します。
`a.php`というファイルのオペコードを表示したいときは、コマンドプロンプトで下記のように記述します。

```
> php -d vld.active=1 -d vld.execute=0 a.php
```

これでオペコードが表示されます。

![vld.jpg](https://qiita-image-store.s3.amazonaws.com/0/72985/c479b049-3c63-1394-bad7-ce26437ec66b.jpeg)

下記のようなエラーが表示されるときは、ダウンロードしたファイルが使用している環境と異なっています。
適切なファイルをダウンロードしてください。

> 有効な Win32 アプリケーションではありません。

# note

note でも記事を公開してるので、興味がある方はご覧ください。

・[【初学者向けコードリーディング】 PHP の TODO アプリのコードを一緒に読み解こう](https://note.mu/7968/n/n46a8beb87c93)