SOY Shopの開発でPHPの深い箇所を意識してコードを書く必要が出てきた。

PHPをより深く理解する為には何から手を付けていけば良いのだろう?ということで、

PHP: Hypertext Preprocessor



技術評論社から発売されているPHPはどのように動くのか~PHPコアから読み解く仕組みと定石を読むことから始めてみた。

この本はPHPの本なのにC言語が頻繁にあり、メモリの確保やインタプリタの説明が少ない状態で話が始まるので、もしこの本を読むのであれば、事前に



O'Reilly Japan - コンピュータシステムの理論と実装



Lambda Note Goならわかるシステムプログラミング



O'Reilly Japan - Go言語でつくるインタプリタあたりは読んでおいた方が良いかもしれない。

※本当はC言語でメモリあたりに触れておいた方が良いけれども、C言語は難しいのでGo言語の方で触れることを勧める。




冒頭の本に戻って、PHPを理解するためにはオペコードを見た方が良いと記載されていた。

オペコードというのは、PHP等の人にとって読みやすい高級言語を機械が解釈する機械語に変換する際の途中で生成する中間コードの事で、

Zend Engine - Wikipedia


例えば、

<?php
echo "Hello World"";

というコードを実行する際に、


0 ECHO 'Hello+World'
1 RETURN  1

上記のようにオペコードに変換して、このオペコードを機械語に変換してプログラムが実行される。




PHPのオペコードを見るにはVLD(Vulcan Logic Dumper)が良いとのことなので、VLDを使えるようにしてみる。

derickr/vld - github.com


今回はPHPのCLIでVLDを使用できるようにする。

環境

OS:Ubuntu 20.04

PHP:PHP 7.4.6


端末を開き、下記のコマンドを実行する。

※事前にGitを使えるようにしておく必要あり

$ git clone https://github.com/derickr/vld.git
$ cd vld
$ phpize
$ ./configure
$ sudo make
$ sudo make install

上記のコマンドを実行すると、vld.soを/usr/lib/php/20190902/以下に作成したというメッセージが表示されるので、cliの方のphp.iniにvldの記述を追加する。

$ sudo nano /etc/php/7.4/cli/php.ini

;extension=xslもしくはextension=xslの次の行にextension=/usr/lib/php/20190902/vld.soを追加する。




早速、VLDを試してみる。

先程のHello World!のコードをa.phpというファイル名で保存して、端末から、

php -d vld.active=1 -d vld.execute=0 /path/to/dir/a.php

を実行してみると、


Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /path/to/dir/a.php
function name:  (null)
number of ops:  2
compiled vars:  none
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
    2     0  E >   ECHO                                                     'Hello+World'
    3     1      > RETURN                                                   1

branch: #  0; line:     2-    3; sop:     0; eop:     1; out0:  -2
path #1: 0, 

が出力された。


これでPHPを理解する為の第一歩の準備ができた。