Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
PHPのOpcodeを 読んでみよう
Search
yasuaki640
October 08, 2023
Programming
1.9k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
PHPのOpcodeを 読んでみよう
yasuaki640
October 08, 2023
More Decks by yasuaki640
See All by yasuaki640
LeetCode x AIで始める コーディング面接対策
yasuaki640
0
88
PHPのFFIを使って簡単なメロディを演奏する
yasuaki640
0
910
TypeScriptで簡易DBを作ってみた
yasuaki640
1
330
Other Decks in Programming
See All in Programming
世界の中心で、AI(App Intents)をさけぶ ー App Intents中心設計の実践ガイド
touyou
0
460
Jetpack Compose メカニズム
skydoves
0
150
XP祭りでしか伝わらないフリップネタ #xpjug
murabayashi
0
150
From 6 People Classroom Meetup to 100 People Regional Conference / FOSS4G Hiroshima 2026
furukawayasuto
0
160
RSSとCodexを使ってX投稿自動化してみた
ochtum
0
110
市販E-Readerを乗っ取れ 〜Embedded Swiftで電子ペーパーガジェットを制御する〜
trickart
0
180
iOSDC2026登壇資料.pdf
riofujimon
0
120
Go × SIMDで高速化するベクトル検索 ~ルーフラインモデルでSIMDが効く境界を探れ! ~
po3rin
1
240
標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127_uuid_decision
convto
5
6.4k
AWS Step Functions 大規模並列の壁を越える / jaws-sonic-2026-niigata-step-functions
kasacchiful
PRO
1
440
[DroidKaigi 2026] Bring your own phones to Gradle Managed Devices
f2lk
0
120
AGENTS.md Is Not Enough:Build Skills, Don't Download Them
lx_t
0
110
Featured
See All Featured
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
Designing Powerful Visuals for Engaging Learning
tmiket
1
540
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
330
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
2.8k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
AI: The stuff that nobody shows you
jnunemaker
PRO
9
990
Why Our Code Smells
bkeepers
PRO
340
58k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
Test your architecture with Archunit
thirion
2
2.4k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.8k
Transcript
PHPのOpcodeを 読んでみよう ディップ株式会社 クライアントエンハンス課 渡邉泰曉 @yasuaki640
この発表のねらい 1. Opcodeを読む準備ができる 2. PHP処理系内部を垣間見、処理系に興味を持てる
Opcodeとは?(wikipediaより抜粋) (機械語に限らず)操作に関する命令のコード。 (中略) アセンブリ言語や仮想機械などの用語として用 いられる。 https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%9A%E3%82%B3%E3%83%BC%E3%83%89
Opcodeとは?(PHPでのダンプ形式) ADD CV0($a) CV1($b) オペコード オペランド(引数)
Opcodeの扱われ方(概要) 1. PHPコードを解析し、AST(抽象構文木)を出力 2. ASTからOpcodeを生成 3. OpcodeをPHP VMが実行 <?php echo
"Hello"; ECHO string("Hello") RETURN int(1) array( 0: Stmt_Echo( exprs: array( 0: Scalar_String( value: Hello ) ... 解析 生成(emit) VMに渡され実行
Opcodeの扱われ方(OPcache使用時) - Opcodeが共有メモリにキャッシュされる - PHPコードの解析~ASTの生成を飛ばすため処理が速い!! <?php echo "Hello"; ECHO string("Hello")
RETURN int(1) array( 0: Stmt_Echo( exprs: array( 0: Scalar_String( value: Hello ) ... 解析 生成(emit) VMに渡され実行 ここだけ実行
Opcodeを読むメリット(個人の感想です) - (手っ取り早く)PHP処理系の挙動を垣間見れる - php-srcリーディングの取っ掛かりとしやすい
Opcodeダンプの設定 - PHP 7.1以降であれば拡張を入れず、簡単に Opcodeダンプを出力できる - 詳細はAppendixに記載
Opcodeを読む <?php $a = 1; $b = 2; $c =
$a + $b; echo $c;
Opcodeを読む <?php $a = 1; $b = 2; $c =
$a + $b; echo $c; $_main: ; (lines=6, args=0, vars=3, tmps=4) ; (before optimizer) ; /workspace/experimental.php:1-6 ; return [] RANGE[0..0] 0000 ASSIGN CV0($a) int(1) 0001 ASSIGN CV1($b) int(2) 0002 T5 = ADD CV0($a) CV1($b) 0003 ASSIGN CV2($c) T5 0004 ECHO CV2($c) 0005 RETURN int(1)
Opcodeを読む $_main: ; (lines=6, args=0, vars=3, tmps=4) ; (before optimizer)
; /workspace/experimental.php:1-6 ; return [] RANGE[0..0] 0000 ASSIGN CV0($a) int(1) 0001 ASSIGN CV1($b) int(2) 0002 T5 = ADD CV0($a) CV1($b) 0003 ASSIGN CV2($c) T5 0004 ECHO CV2($c) 0005 RETURN int(1) 実行時のメタ情報 ダンプされた Opcode
Opcodeを読む - PHP公式に各Opcodeの説明が記載 http://php.adamharvey.name/manual/ja/internals2.opcodes.php
Opcodeを読む 0000 ASSIGN CV0($a) int(1) 0001 ASSIGN CV1($b) int(2) 0002
T5 = ADD CV0($a) CV1($b) 0003 ASSIGN CV2($c) T5 0004 ECHO CV2($c) 0005 RETURN int(1) PHPスクリプト上の 実際の変数($a, $b) に値を代入
Opcodeを読む 0000 ASSIGN CV0($a) int(1) 0001 ASSIGN CV1($b) int(2) 0002
T5 = ADD CV0($a) CV1($b) 0003 ASSIGN CV2($c) T5 0004 ECHO CV2($c) 0005 RETURN int(1) 加算を実行し、 VM上の一時変数(T5)に 値を代入
Opcodeを読む 0000 ASSIGN CV0($a) int(1) 0001 ASSIGN CV1($b) int(2) 0002
T5 = ADD CV0($a) CV1($b) 0003 ASSIGN CV2($c) T5 0004 ECHO CV2($c) 0005 RETURN int(1) VM上の一時変数(T5)の値を PHPスクリプト上の 実際の変数($c)に代入
Opcodeを読む 0000 ASSIGN CV0($a) int(1) 0001 ASSIGN CV1($b) int(2) 0002
T5 = ADD CV0($a) CV1($b) 0003 ASSIGN CV2($c) T5 0004 ECHO CV2($c) 0005 RETURN int(1) 加算結果が代入された 変数に対しechoを実行
Opcodeを読む 0000 ASSIGN CV0($a) int(1) 0001 ASSIGN CV1($b) int(2) 0002
T5 = ADD CV0($a) CV1($b) 0003 ASSIGN CV2($c) T5 0004 ECHO CV2($c) 0005 RETURN int(1) PHP側で 暗黙的に付与されるreturn ※詳細は略
Opcodeのハンドラを読む - マニュアルに説明がないOpcodeもある - php-srcに、Opcodeのハンドラ(処理の実体)を探して 読む - 今回はハンドラの探し方まで紹介
Opcodeのハンドラを読む <?php function welcome(string $target): string { $hi = 'Welcome
to' . $target; return $hi; } echo welcome('PHP conference!'); $_main: (省略) 0000 INIT_FCALL 1 144 string("welcome") 0001 SEND_VAL string("PHP conference!") 1 0002 V0 = DO_UCALL 0003 ECHO V0 0004 RETURN int(1) welcome: (省略) 0000 CV0($target) = RECV 1 0001 T2 = CONCAT string("Welcome to") CV0($target) 0002 ASSIGN CV1($hi) T2 0003 VERIFY_RETURN_TYPE CV1($hi) 0004 RETURN CV1($hi) 0005 VERIFY_RETURN_TYPE 0006 RETURN null
Opcodeのハンドラを読む welcome: (省略) 0000 CV0($target) = RECV 1 0001 T2
= CONCAT string("Welcome to") CV0($target) 0002 ASSIGN CV1($hi) T2 0003 VERIFY_RETURN_TYPE CV1($hi) 0004 RETURN CV1($hi) 0005 VERIFY_RETURN_TYPE 0006 RETURN null 引数の型チェック?? (ドキュメントに説明がない)
Opcodeのハンドラを読む - php-srcのzend_vm_execute.hに実際の処理が書 かれている ZEND_{Opcode名}_SPEC_{オペランドの種別}_HANDLER
Opcodeのハンドラを読む static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED_HANDLER (ZEND_OPCODE_HANDLER_ARGS) { オペコード名 オペランドの種別
Opcodeのハンドラを読む - ソースを読むだけではわからないことも多い - 本当にそのハンドラが呼ばれているのか? - デバッガを使う - 手順はネット上に豊富なため割愛
Opcodeのハンドラを読む
まとめ - PHPコードは内部でOpcodeにコンパイルされる - Opcodeを読むことは、php-srcリーディングなど深淵 の入り口におすすめ - パフォーマンスのため、OPcacheはちゃんと設定しよ う
採用やってます!!! - QRコードを読み取り、カジュアル面談しましょう!!
Appendix
参考にさせていただいた記事 - php-srcを読んでみよう - https://fortee.jp/phpcon-2022/proposal/1addf51d-6f72-4c96-9337-034ec6cc0643 - PHP による hello world
入門 - https://tech.respect-pal.jp/php-helloworld - PHP 7 Virtual Machine - https://www.npopov.com/2017/04/14/PHP-7-Virtual-machine.html - How to dump and inspect PHP OPCodes - https://php.watch/articles/php-dump-opcodes - Static Optimization of PHP bytecode (PHPSC 2017) - https://www.slideshare.net/nikita_ppv/static-optimization-of-php-bytecode-phpsc-2017 - Zend Engine 2 オペコード (PHP公式マニュアル) - http://php.adamharvey.name/manual/ja/internals2.opcodes.php - OPcache (PHP公式マニュアル) - https://www.php.net/manual/en/book.opcache.php - Implementing a Range Operator into PHP - https://phpinternals.net/articles/implementing_a_range_operator_into_php - Using CLion with php-src - https://dev.to/ramsey/using-clion-with-php-src-4me0
Opcodeダンプの設定 - .iniファイルでOPcacheの設定を有効にする - 今回はCLI版での実行を想定 zend_extension=opcache opcache.enable_cli=1
Opcodeダンプの設定 - スクリプト実行時にOpcodeダンプ出力のオプションを 渡す php -d opcache.opt_debug_level=0x10000 sample.php