SlideShare a Scribd company logo
PHP で実⾏中のスクリプトの動
作を下から覗き⾒る
五⼗嵐 進⼠ / @sji_ch
私は誰ですか
五⼗嵐 進⼠
スマートホンゲームのサーバサイドプログラマー
⼤体は PHP のコードを読み書きして過ごしてる
昨年娘ができた
PHP カンファレンス仙台とかやりました
PHP 歴は累計 7 年くらい
元は趣味で C ⾔語を少し
PHP で実行中のスクリプトの動作を下から覗き見る
Agenda
php-pro ler の紹介
下からのぞき⾒るとは
php-pro ler の実装
活⽤例
将来の展望
php-pro ler の紹介
php-pro ler とは
実⾏中の PHP スクリプトからコールトレースを抜き取るツール
元々 ruby で同様のことをやる rbspy という rust 製のプログラム
がある
https://github.com/rbspy/rbspy
rbspy をパクった phpspy という C ⾔語製のプログラムがある
https://github.com/adsr/phpspy
この phpspy を更にパクった PHP 製のツールが php-pro ler
https://github.com/sj-i/php-pro ler
デモ
下からのぞき⾒るとは︖
コンピュータシステムは階層的なシステム
物理的な⼟台に上物が乗っていくイメージ
階層の上のほうにある技術 = ⾼レイヤー
階層の下のほうにある技術 = 低レイヤー
PHP は PHP より低いレイヤーの仕組みで動いてる
php-pro ler は PHP より低いレイヤーの仕組み越しに PHP スク
リプトの挙動へアクセスするツール
前提知識
PHP でコードを書いている分には普通あまり意識しない前提知
識が必要
例えばコンピュータはなぜ動くのか
https://www.amazon.co.jp/dp/4822281655
例えば Linux の仕組み
https://www.amazon.co.jp/dp/B079YJS1J1/
CPU
コンピュータの部品
電気信号をコンピュータを動かすための命令として解釈
様々な計算処理を⾏う
接続された他機器を操作するための電気信号を送る
⾃⾝への命令はメモリから読むこむ
メモリ
それぞれ背番号を持ち 1 バイト分の情報を保持する領域の並び
16GB なら背番号 0 から 170 億番くらいまでの範囲
背番号を番地またはアドレスと呼ぶ
各番地の情報を取り出せる
プログラム = CPU への命令はメモリへ読み込むことで CPU から
実⾏可能
OS のプロセス
OS の機能により、コンピュータ上では複数のプログラムが同時
に動作(マルチタスク / マルチプロセス)
OS 上で動作中のプログラムのことをプロセスと呼ぶ
プロセス間のメモリは隔離されてる
複数のプロセスがお互いに意図せぬ⼲渉をすると困る
OS は各プロセスがそれぞれ固有のメモリを持つかのようにプロ
セス間の環境を隔離
CPU の機能を利⽤して実現
プロセス間のメモリは隔離されてる
同じメモリアドレスでもプロセスが違えば異なる内容を持ち得る
別プロセスのメモリに普通の⽅法でアクセスすることはできない
PHP スクリプトの動作
PHP は⾼級⾔語
CPU によって直接解釈される命令列(機械語)ではない
機械語
機械語は CPU にプログラムを実⾏させるための命令列
同じ信号のパターンが別の CPU では違った意味を持つ
別の種類の CPU で同じプログラムを動かそうとした時、移植が
困難
⼈間より機械の都合にあわせた⾔語
⾼級⾔語
より⼈間の都合にあわせた⾔語
何らかの形でプログラムにより機械語へ翻訳して使う
最初から翻訳が前提なので移植性が⾼い
型の保護などにより動作検証性やメンテナンス性を保ちながらプ
ログラムを作れる
複数⼈でプロジェクトの⾼度な概念を共有するのにも使える
処理系
ある⾔語から別の⾔語への翻訳処理をコンパイルと呼ぶ
プログラムをコンパイルまたは逐次解釈で実⾏するためのプログ
ラムを、その⾔語の処理系と呼ぶ
⾼級⾔語で更に⾼級⾔語が作られる
C は⾼級⾔語の中では機械語に近い
⼈間の都合に寄り切ってない
C でより⾼級な⼈間の都合寄りの別の⾔語が作られている
PHP 処理系は C で書かれている
PHP 処理系
PHP の処理系はある種の仮想マシン
PHP スクリプトはまずメモリ上でこの仮想マシンのための機械
語命令列にコンパイル
仮想マシンのための機械語命令=オペコード
仮想マシンがこのオペコード列を実⾏
PHP 処理系の状態はメモリ上にある
PHP 処理系の仮想マシンはプログラムであり、メモリ上に⾃⾝
の状態を持つ
今現在コンパイルされた命令列のどの位置を実⾏しているか
実⾏中の関数からの return 先の命令位置はどこか等
php-pro ler の実装
モチベーション
スクリプトの性能計測やトラブルシュートの道具がほしい
処理系のプロセス外から処理系の状態を盗み⾒たい
なぜプロセス外から⾒たいか
xdebug や xhprof はフック型プロファイラ
フック型では計測対象の実⾏性能に影響を与えてしまう
なぜプロセス外から⾒たいか
別プロセスから勝⼿に覗き込むなら、CPU コアが余ってれば性
能劣化は回避可能
何か間違ってもツールの⽅が落ちるだけ
調査対象への影響が少なければ本番環境での利⽤も視野に⼊って
くる
調査対象プロセス暴⾛時の原因調査にも使える
基本的アイディア
PHP スクリプトは仮想マシンの状態を変化させながら動作
仮想マシンの状態は処理系が動作するプロセス⽤のメモリ領域に
保存
以下 2 つの材料が揃えば覗き⾒できる
別プロセスの指定番地のメモリ内容を覗き⾒る⽅法
別プロセスのメモリ内のどの番地に何のデータがあるかを知
る⽅法
コールトレース
⼀⼝に処理系の状態といっても⾊々ある
今回欲しいのはコールトレース
実⾏中の関数がどの関数から呼ばれて、更にその関数がどの関数
から呼ばれて、という奴
なぜコールトレースか
よくあるプログラムは関数呼び出しの繰り返しで構成
ある関数が別の関数を呼び出して、終わったら次の関数を呼び出
して、と進んでいく
コールトレースのサンプリング
「今何を実⾏中か」のコールトレースを、⼤体等間隔でサンプリ
ングして取る
よく現れる関数は処理時間が⻑かったり頻繁に呼び出されたり
で、多くの時間を使っている確率が⾼い
性能問題やシステムが無応答となるような問題の原因を突き⽌め
やすくなる
FFI で PHP からシステムコールを呼ぶ
FFI
去年リリースされた PHP 7.4 の機能
Foreign Function Interface の略
PHP から他の⾔語で作られた関数を呼び出すための機能
FFI 導⼊以前
7.3 までの PHP は PHP 単体でできないことが多かった
PHP Manual に載っている標準関数の範囲外は C の拡張機能を作
る or 導⼊する必要があった
実は標準関数⾃体も処理系に標準添付されている拡張という形で
実現されている
PHP の拡張を作るには特殊な作法と⼀定以上の C ⾔語の知識が
必要
FFI 導⼊以降
FFI 以外の拡張を使わず C ⾔語資産を PHP から直接呼び出せる
システムコールやメモリ操作の関数、処理系の内部関数もそのま
ま呼べる
当然そのリスクも⼀緒に持ち込まれる
C ⾔語 や PHP 処理系内部の深い知識、拡張を書く際の特有の作
法はいらなくなる
しかもそういうコードを composer からインストールできる
FFI の使い⽅
$ffi = FFI::cdef(
'int printf(const char * restrict format, ... );',
// 'libc.so' /* libc は処理系とともに読み込まれているので不要 */
);
$ffi->printf('hello clang world');
process_vm_readv
Linux のシステムコール
プロセスのアドレス空間間でデータを転送する
対象プロセス ID と対象プロセス内でのメモリアドレス、データ
サイズ、⾃プロセスのバッファを指定して呼ぶ
別プロセスのデータを⾃プロセスの指定バッファ内へコピー可能
process_vm_readv の使⽤条件
呼び出し元は以下を満たす必要がある
CAP_SYS_PTRACE という特別な権限を持ったプロセス
対象プロセスと同ユーザ / グループのプロセス
gdb でプロセスにアタッチする時と⼤体同じ権限があればいける
脳死で sudo しててもダイジョブ
/proc/<pid>/maps
procfs
Process Filesystem の略
/proc/ 下の擬似的なファイルとして、linux のプロセスに関する
様々な情報を取得できる
ps コマンドなども procfs の内容を解釈して出⼒するような実装
https://gitlab.com/procps-ng/procps
/proc/<pid>/maps
pid のプロセス内で、どのファイルがどのメモリアドレスに読み
込まれている、というマッピング情報を提供するもの
使われている各実⾏ファイルや共有ライブラリのメモリ上での位
置が分かる
PHP からはファイルとして開いて正規表現等でパース可能
/proc/<pid>/maps の例
address perms offset dev inode pathname
5636ed586000-5636ed692000 r--p 00000000 08:01 3672367 /usr/local/bin/php
5636ed786000-5636edb19000 r-xp 00200000 08:01 3672367 /usr/local/bin/php
5636edb86000-5636ee36c000 r--p 00600000 08:01 3672367 /usr/local/bin/php
5636ee6df000-5636ee786000 r--p 00f59000 08:01 3672367 /usr/local/bin/php
5636ee786000-5636ee78d000 rw-p 01000000 08:01 3672367 /usr/local/bin/php
...
7f872b6df000-7f872b6e0000 r--p 00000000 08:01 2238306 /lib/x86_64-linux-gnu/ld-2.28.so
7f872b6e0000-7f872b6fe000 r-xp 00001000 08:01 2238306 /lib/x86_64-linux-gnu/ld-2.28.so
7f872b6fe000-7f872b706000 r--p 0001f000 08:01 2238306 /lib/x86_64-linux-gnu/ld-2.28.so
7f872b706000-7f872b707000 r--p 00026000 08:01 2238306 /lib/x86_64-linux-gnu/ld-2.28.so
7f872b707000-7f872b708000 rw-p 00027000 08:01 2238306 /lib/x86_64-linux-gnu/ld-2.28.so
ELF
ELF とは
これではない
ELF とは
プログラムコードを格納するファイル形式
Executable and Linkable Format の略
プログラムで使うための機械語コードやデータとシンボル情報な
どの付加情報をまとめたもの
シンボル情報
関数や変数の名前からファイル内への位置を引っ張り出すための
索引情報
分割コンパイルとリンク
C ⾔語などでは普通コードをファイルごとに分割でコンパイル
分割されたコード断⽚を⼀つの実⾏可能ファイルへリンク
リンクの際には各ファイルの何バイト⽬にどの関数がある、とい
った情報が必要(この際にシンボル情報が使われる)
動的リンク
ディスクやメモリ容量削減のため、リンクのタイミングは実⾏の
直前まで後回しにできる
実⾏時リンクとか動的リンクと呼ばれる
この際に実⾏可能ファイルと実⾏時にリンクされるのが、共有ラ
イブラリとか共有オブジェクトと呼ばれるファイル
Windows では .dll、Linux 等では .so とか呼ばれる
実⾏可能ファイルのシンボル情報
⼀度完全にリンクされればシンボル情報は不要となる
容量削減の観点からファイルから削除することも可能(strip)
実際には実⾏時リンクのため、⼀部のシンボル情報は実⾏可能フ
ァイルになっても残しておく必要がある
PHP 処理系のシンボル情報
mod_php でも cli や fpm でも、拡張機能を共有オブジェクト /
DLL で必要に応じてロードできる
拡張から PHP のコア機能にアクセスするためのシンボル情報は
処理系に付いてくる
処理系の ELF ファイルを解釈してシンボル情報を読み込めば、
これらの関数やデータがどの位置にあるかが分かる
拡張から可能なのに近いレベルで情報が取れる
PHP で ELF を読む
php-pro ler では ELF パーサを⾃前で書いてみた
PHP で書いたの俺以外に世界で 5 ⼈くらいしかいない説がある
案外普通に書けた
PHP でバイナリデータを読む
ArrayAccess で添え字でバイト列から 1 バイト分の整数値を読み
込めるようにする
interface ByteReaderInterface extends ArrayAccess
PHP の⽂字列はエンコード情報を持たないバイト列
添え字アクセスと ord() で 1 バイト分のデータを取り出す実
装が作れる
final class StringByteReader implements ByteReaderInterface
{
use ByteReaderDisableWriteAccessTrait;
public function offsetGet($offset): int
{
return ord($this->source[$offset]);
}
このインターフェースを通じて 32 ビットや 64 ビットの整数値
を取り出すクラスも作る
final class LittleEndianReader implements IntegerByteSequenceReader
{
public function read8(ByteReaderInterface $data, int $offset): int
{
return $data[$offset];
}
public function read16(ByteReaderInterface $data, int $offset): int
{
return ($data[$offset + 1] << 8) | $data[$offset];
}
public function read32(ByteReaderInterface $data, int $offset): int
{
return ($data[$offset + 3] << 24)
| ($data[$offset + 2] << 16)
| ($data[$offset + 1] << 8)
| $data[$offset];
}
PHP でのバイナリ読みで困ったところ
PHP では符号なし 64 ビット整数が普通には扱えない
int は 64 ビット版 PHP でも符号あり整数値
評価値が上限値である PHP_INT_MAX を超える式の値は、整数
同⼠の演算であっても oat へ暗黙キャスト
真⾯⽬に扱うと多倍超演算⽤の拡張である gmp を使うとか
今回は int で押し通してる
今回は敢えて PHP の int をそのまま使っている
int で⾜りないのはどんな時か
ディスク上やメモリ上の ELF ファイルを読み込む上でどこに符
号なしの 64bit 整数値が使われるか
今回の⽤途では ELF 内でアドレスやサイズを保持する型を使
う時
Linux プロセスのメモリレイアウトを確認してみる
x86-64 のみ考慮
ユーザ空間のメモリアドレス上限は符号あり整数値の範囲内にお
さまる
符号なし 64bit 整数値を扱う必要が出るのはカーネル空間のメモ
リアドレスを取り扱いたくなった時
https://www.kernel.org/doc/Documentation/x86/x86_64/mm.txt
PHP: Hypertext Preprocessor
カーネル空間のメモリアドレスを PHP で扱おうとするのが間違
っている
PHP が何の略だと思っているのか
ZendEngine
ZendEngine とは
PHP の処理系のコアは ZendEngine と呼ばれている
PHP 4 の頃に Zeev さんと Andi さんが処理系のコアを刷新
⼆⼈の名前から Ze と nd をとって Zend
Zend Technologies という会社が作られたりした
これを⺟体に ZendFramework というフレームワークが作ら
れたりもした
ZendEngine のコンパイラと仮想マシン
ZendEngine は、雑に⼤きく分けると以下 2 つから成り⽴つ
PHP スクリプトを仮想マシンのコードへ変換するコンパイラ
それを実⾏する仮想マシン
仮想マシン部分は Executor とも呼ばれている
仮想マシンの状態
Executor Globals(EG) というグローバル変数の構造体に仮想マシ
ンの状態が格納
zend_execute_data
EG には zend_execute_data 型の current_execute_data というメ
ンバがある
現在実⾏中の仮想マシン命令についての情報が含まれている
元はどの関数のコードから⽣成されたものか
どの PHP スクリプトファイルの何⾏⽬から⽣成されたもの
か
prev_execute_data というメンバがある
同じ構造で関数の呼び出し元の情報が⼊ってる
ZendEngine の構造体を PHP で読む
Executor Globals や zend_execute_data は C ⾔語の構造体
C ⾔語構造体を PHP 側で 1 バイトずつ解釈するコードを書くの
は少し⾯倒
FFI の機能で型キャストがある
process_vm_readv で得たデータへのポインタをキャストすれば
FFI 経由でアクセス可能
PHP 処理系のソースから必要な構造体定義を抜き出して使う
ZendEngine の構造体を PHP で読む際の注意点(1)
FFI は C ⾔語のマクロに対応してないので、展開しておく必要が
ある
ZendEngine の構造体を PHP で読む際の注意点(2)
処理系のバージョンが違えば内部構造も変わるので、各 PHP バ
ージョン⽤の定義が必要
ZendEngine の構造体を PHP で読む際の注意点(3)
データ内でポインタのアドレスはコピー元プロセスでのアドレス
を指している
そのままだと FFI が無効なポインタをたどろうとして SEGV
構造体定義側でポインタを整数値型に変更
ポインタをたどる時は繰り返し process_vm_readv して⼿動でた
どる
ZendEngine 内部の参考資料
PHP と SAPI と ZendEngine3 と
PHP の関数実⾏とその計測
PHP による hello world ⼊⾨
https://www.slideshare.net/do_aki/php-sapi-zendengine3
https://qiita.com/sj-i/items/836fa5a5e246961c40b6
http://tech.respect-pal.jp/php-helloworld/
活⽤例
スクリプトの⾼速化
The Computer Language Benchmarks
複数⾔語でおおむね等価な処理を書いて、実⾏性能をベンチマー
ク
https://benchmarksgame-
team.pages.debian.net/benchmarksgame/index.html
nbody benchmark
まあまあレガシーな雰囲気のコード
Node での実⾏結果 8 秒に対して、PHP(7.4) での実⾏結果が 235
秒
⼿元のマシンでは Node で 3.6 秒、PHP(7.4) 118 秒
https://benchmarksgame-
team.pages.debian.net/benchmarksgame/program/nbody-php-
3.html
書き直してみた⼈がいる
⽐較的モダンっぽく⾒えるバージョンに書き直した⼈が
https://gist.github.com/Girgias/e21b57cff72b8d05be06883d98552
遅くなってしまった
⼿元のマシンで⼤体 174 秒ほど、遅くなってしまった
PHP8 にして JIT コンパイラを使えば 85 秒
でも修正前なら JIT で 48 秒
プロファイルをとる
php-pro ler でスクリプトの計測をとる
出⼒を少し調整、どの関数のどの⾏かだけでなく、どの仮想マシ
ン命令を実⾏中かも出す
php スクリプトなのでちょっとした修正が簡単
https://github.com/sj-i/php-pro ler/tree/experiment-opcode-
tracer
ワンライナーで集計
結果をファイルに吐き、重複⾏をカウントし、カウントの順でソ
ート
time php ./n-body-test.php 50000000
sudo ./php-profiler inspector:trace -p 250359 >result
cat result | sort | uniq -c | sort -nr
プロファイル結果
NBodySystem::advance() 内 130 〜 144 ⾏⽬あたりが重そう
オペコードでは 60 番と 12 番、28 番と 82 番が頻出
https://gist.github.com/sj-
i/d0cbc6c0baa414ffcd00be6840a9166f
頻出オペコード
60 番 ZEND_DO_FCALL は関数呼び出しの命令
ここからの関数呼び出し(NBodySystem::advance)が重い
12 番 ZEND_POW は累乗演算⼦の命令、妙に重い
28 番 ZEND_ASSIGN_OBJ_OP と 82 番 ZEND_FETCH_OBJ_R はオ
ブジェクトのプロパティへのアクセス⽤命令
ZEND_POW の対応
累乗演算⼦で 2 乗している部分を普通の乗算に書き換え
修正前
修正後
$distance² = $dx**2 + $dy**2 + $dz**2;
$distance² = $dx*$dx + $dy*$dy + $dz*$dz;
プロパティアクセスの対応(1)
最内ループのプロパティアクセスで外側へ出せるものを移動
修正前
foreach ($this->bodies as $index => $referenceBody) {
$nbBodies = count($this->bodies);
for ($i = $index + 1; $i < $nbBodies; ++$i) {
$body = $this->bodies[$i];
$dx = $referenceBody->x - $body->x;
$dy = $referenceBody->y - $body->y;
プロパティアクセスの対応(1)
最内ループのプロパティアクセスで外側へ出せるものを移動
修正後
foreach ($this->bodies as $index => $referenceBody) {
$nbBodies = count($this->bodies);
$rbx = $referenceBody->x;
$rby = $referenceBody->y;
for ($i = $index + 1; $i < $nbBodies; ++$i) {
$body = $this->bodies[$i];
$dx = $rbx - $body->x;
$dy = $rby - $body->y;
プロパティアクセスの対応(2)
PHP の型宣⾔は実⾏時に型検査のコストがかかるので外す
修正前
public float $x;
public float $y;
public float $z;
public float $vx;
public float $vy;
public float $vz;
public float $mass;
プロパティアクセスの対応(2)
PHP の型宣⾔は実⾏時に型検査のコストがかかるので外す
修正後
public $x;
public $y;
public $z;
public $vx;
public $vy;
public $vz;
public $mass;
最適化の効果
書き換え後のコードで JIT 有効で実⾏すると 29 秒に
85 秒 → 29 秒、約 3 倍⾼速化
3.6 秒の Node(V8) とはまだ 8 倍くらいの差
プロパティアクセスが遅めなの⾃体は JIT でも変わらず、PHP 8
の今後に期待
将来の展望
C ⾔語側までトレースを取る
ptrace システムコールで対象プロセスの実⾏を⼀瞬⽌めれば
CPU 的な状態も取得できる
C プログラムのデバッグ⽤情報を格納する DWARF 形式を使う
両⽅使えば更に細かい C ⾔語側のトレースまで取れる筈
PHP コードのどの関数のどの⾏のどのオペコードを実装して
いるどの処理系内の C ⾔語関数が遅いのか
「なぜか echo に 7 秒かかる」等の性能調査や処理系⾃体の性能
改善に使えそう
ELF
DWARF
時間を⽌める能⼒(ptrace)
別世界(別プロセス)の記憶(メモリー)
なろう系では︖︖︖
今回話していないこと
ZTS 対応のため ELF の TLS からデータを引っ張り出す闇の技
ext-parallel 経由でのマルチスレッド利⽤
preloading とマルチスレッド
amphp での⾮同期処理
静的型検査と Promise
JIT でのトレース取得性能
⼀部は PHP カンファレンス 2020 オンラインで話す予定
おしまい

More Related Content

PPTX
VimExcelのご紹介
PDF
Yoctoで綺麗なkernel configを作る
PDF
PHP-FPM の子プロセス制御方法と設定をおさらいしよう
PDF
PHPでマルチスレッド
PPTX
php and sapi and zendengine2 and...
PDF
Pythonでパケット解析
PDF
YoctoでLTSディストリを作るには
PDF
Jbatch実践入門 #jdt2015
VimExcelのご紹介
Yoctoで綺麗なkernel configを作る
PHP-FPM の子プロセス制御方法と設定をおさらいしよう
PHPでマルチスレッド
php and sapi and zendengine2 and...
Pythonでパケット解析
YoctoでLTSディストリを作るには
Jbatch実践入門 #jdt2015

What's hot (20)

PDF
PHP 8 と V8 (JavaScript) で速さを見比べてみよう!
PDF
社内ドキュメント検索システム構築のノウハウ
PDF
今日から使おうSmalltalk
PDF
WebSocketのキホン
PPTX
知らないと損するアプリ開発におけるStateMachineの活用法(full版)
PPTX
ここがつらいよWebRTC - WebRTC開発の落とし穴
PPTX
CleanArchitecture 第4部 「コンポーネントの原則」
PPTX
PHP と SAPI と ZendEngine3 と
PDF
モノタロウの開発・リリースサイクルを支えるJenkinsの活用事例 - Jenkins Day Japan 2021
PDF
文字コードに起因する脆弱性とその対策(増補版)
PDF
Zynq MPSoC勉強会 Codec編
ODP
SPAのルーティングの話
PDF
PlaySQLAlchemy: SQLAlchemy入門
PDF
C#×LLVM=アセンブラ!? 〜詳説・Burstコンパイラー〜
PDF
Rust で RTOS を考える
PPTX
Zynq + Vivado HLS入門
PDF
Bonfire API #1 APIのリトライ処理
PDF
JIT のコードを読んでみた
PDF
Smalltalkだめ自慢
PDF
わかった気になるMySQL
PHP 8 と V8 (JavaScript) で速さを見比べてみよう!
社内ドキュメント検索システム構築のノウハウ
今日から使おうSmalltalk
WebSocketのキホン
知らないと損するアプリ開発におけるStateMachineの活用法(full版)
ここがつらいよWebRTC - WebRTC開発の落とし穴
CleanArchitecture 第4部 「コンポーネントの原則」
PHP と SAPI と ZendEngine3 と
モノタロウの開発・リリースサイクルを支えるJenkinsの活用事例 - Jenkins Day Japan 2021
文字コードに起因する脆弱性とその対策(増補版)
Zynq MPSoC勉強会 Codec編
SPAのルーティングの話
PlaySQLAlchemy: SQLAlchemy入門
C#×LLVM=アセンブラ!? 〜詳説・Burstコンパイラー〜
Rust で RTOS を考える
Zynq + Vivado HLS入門
Bonfire API #1 APIのリトライ処理
JIT のコードを読んでみた
Smalltalkだめ自慢
わかった気になるMySQL
Ad

Similar to PHP で実行中のスクリプトの動作を下から覗き見る (20)

PPTX
php-src の歩き方
PDF
PHPの今とこれから2020
PDF
FukuokaPHP 3
PDF
PHPの今とこれから2022
PPTX
PHPCON_TOKYO_2022_Bigginer.pptx
ODP
Programming camp Codereading
PDF
レガシーなWebアプリケーションと向き合う
PDF
なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い
PDF
Arduino を PHP で制御する
PDF
phpext-2-takagi
PDF
第21回Creators MeetUp
PPT
NanoA
PPTX
Power shell で DSL
PDF
PHP 8 で Web 以外の世界の扉を叩く
PDF
PHPの今とこれから2016
PDF
PHPの今とこれから2015
PDF
Windows で PHP をビルドしてみた
PDF
PHPの今とこれから 2013
PDF
WTM53 phpフレームワーク いまさらcodeigniter
PDF
筋トレ大事
php-src の歩き方
PHPの今とこれから2020
FukuokaPHP 3
PHPの今とこれから2022
PHPCON_TOKYO_2022_Bigginer.pptx
Programming camp Codereading
レガシーなWebアプリケーションと向き合う
なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い
Arduino を PHP で制御する
phpext-2-takagi
第21回Creators MeetUp
NanoA
Power shell で DSL
PHP 8 で Web 以外の世界の扉を叩く
PHPの今とこれから2016
PHPの今とこれから2015
Windows で PHP をビルドしてみた
PHPの今とこれから 2013
WTM53 phpフレームワーク いまさらcodeigniter
筋トレ大事
Ad

PHP で実行中のスクリプトの動作を下から覗き見る