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
89
PHPのFFIを使って簡単なメロディを演奏する
yasuaki640
0
910
TypeScriptで簡易DBを作ってみた
yasuaki640
1
330
Other Decks in Programming
See All in Programming
【DroidKaigi 2026】「アクセシビリティを利用するとき、 アクセシビリティもまたこちらを利用している」 〜マルウェアによる攻撃と防衛について〜
halunoyo
0
460
AI に Inclusive UI を書かせよう — Design Rules Skill で Compose UI を作り直す
theoriatec2024
1
490
仕様駆動開発による爆速プロダクト開発 / Bakusoku Spec Driven Development
kobakei
0
110
How I Stole PSI from Android Studio - DroidKaigi2026
worker8
0
130
Claude Codeを組織的に動かして月400PRを実現した話
happy_ryo
0
280
「新人AI禁止のその先へ ― 参加と協働のステップアップ」Vibe TOKYO, AI & CRAFT / 2026年8月21日
kentarowada
0
100
LoopHub - ローカルで動く GitHub で、AI と共同開発
jugyo
1
550
Go のフラットな パッケージに 「ファイル単位の private」を 〜Linter “declscope” を作った話〜
mpyw
0
320
AI Agent時代のリアーキテクチャ戦略と実践
hokaccha
9
4.5k
テストを司るデーモンに会いに行く 〜隔離した仮想マシンでテストを通すまで〜
h1d3mun3
1
360
From 6 People Classroom Meetup to 100 People Regional Conference / FOSS4G Hiroshima 2026
furukawayasuto
0
200
GraphRAGのKnowledge Graphを 直接!見る/View-GraphRAG's-KnowledgeGraph-directly!
tyumugi1113
1
320
Featured
See All Featured
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.5k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.6k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
69
65k
Marketing to machines
jonoalderson
1
5.8k
Bootstrapping a Software Product
garrettdimon
PRO
306
120k
Utilizing Notion as your number one productivity tool
mfonobong
4
590
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
The SEO Collaboration Effect
kristinabergwall1
1
560
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
540
Rails Girls Zürich Keynote
gr2m
96
14k
How Software Deployment tools have changed in the past 20 years
geshan
1
34k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
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