Upgrade to Pro — share decks privately, control downloads, hide ads and more …

入門Hello world(PHPカンファレンス2022)

yutaron
September 24, 2022

入門Hello world(PHPカンファレンス2022)

PHPカンファレンス2022発表用

yutaron

September 24, 2022
Tweet

Other Decks in Programming

Transcript

  1. 入門
    Hello world

    View Slide

  2. 自己紹介
    ● 西 祐太郎 (長崎県産🐟)
    ● 何でも屋さん@某クラウドソーシング会社
    ○ 専門学校 -> 中堅SI-> Webマーケ系スタートアップ
    -> オンライン旅行代理店
    ● 趣味:距離ガバドライブ🚗
    ● PHPカンファレンスは2020から参加
    ● GitHub: https://github.com/yuta-ron
    ● Wantedly: https://www.wantedly.com/id/yutaron

    View Slide

  3. ● 1-2ヶ月に1回WordPress Meetup (大田区近辺) で遊んでいます
    ○ エンジニアはあまりいません。
    ○ 主に会社のWeb担当とかマーケターとか個人事業主
    ○ 趣味でホームページやっている人とか
    ● 興味のある方はこちらから
    https://www.meetup.com/ja-JP/tokyo-wordpress-meetup/
    自己紹介(告知)

    View Slide

  4. 今日話すこと
    ● 純粋なPHPのお話です。
    ● ブラウザがリクエストを投げて、帰ってくるまでのお話です。
    話さないこと
    ● Laravel/CakePHPなどのフレームワークの話

    View Slide

  5. 前提条件
    ● nginx1.23.1 (Source) + PHP 8.1.10 (Docker)

    View Slide

  6. 期待する動作

    View Slide

  7. 準備するもの
    ● 適切なマシン
    (今回はMacBookAir M1 (Monterey)を使用。なんでもOKです)
    ● ソースコード
    ○ php/php-src (コード追いかける用)
    ○ nginx/nginx (デバッグビルドして適当にログ入れるとイメージ湧きます)
    ● WireShark (パケットさえ見れればなんでもOKです)

    View Slide

  8. PHPがどう動くか
    ❯ php -a
    Interactive shell
    php > echo 'Hello world';
    Hello world
    php >

    View Slide

  9. PHPが実行されるまで
    ● PHPはコードがそのまま実行されるわけではありません。
    ○ インタプリタ言語(リクエストの度に処理実行)
    ● コンパイルする(バイトコード生成)
    ○ 字句解析 ->(トークン化)-> 構文解析
    ■ 抽象構文木 (AST)
    ● 毎回コンパイルするんじゃ効率悪いよ🥺
    ○ これをキャッシュ(OPCache PHP5.5~)
    ■ バイトコードをZend VM上で実行

    View Slide

  10. PHPが実行されるまで
    ● PHPはコードがそのまま実行されるわけではありません。
    ○ インタプリタ言語(リクエストの度に処理実行)
    ● コンパイルする(バイトコード生成)
    ○ 字句解析 ->(トークン化)-> 構文解析
    ■ 抽象構文木 (AST)
    ● 毎回コンパイルするんじゃ効率悪いよ🥺
    ○ これをキャッシュ(OPCache PHP5.5~)
    ■ バイトコードをZend VM上で実行

    View Slide

  11. ここまでの心境
    ● 気になりまくり
    ○ バイトコードって何やねん(もやもや☁)

    View Slide

  12. ここまでの心境
    ● バイトコードって何やねん(もやもや☁)
    ○ お、簡単に見れるらしいぞ。
    https://www.php.net/manual/ja/opcache.configuration.php

    View Slide

  13. PHPが実行されるまで
    ● PHPはコードがそのまま実行されるわけではありません。
    ○ インタプリタ言語(リクエストの度に処理実行)
    ● コンパイルする(バイトコード生成)
    ○ 字句解析 ->(トークン化)-> 構文解析
    ■ 抽象構文木 (AST)
    ● 毎回コンパイルするんじゃ効率悪いよ🥺
    ○ これをキャッシュ(OPCache PHP5.5~)
    ■ バイトコードをZend VM上で実行

    View Slide

  14. PHPがどう分解されていくか(字句解析編)
    ● 今回はこのような簡単なコードで検証

    View Slide

  15. PHPがどう分解されていくか(字句解析編)
    ● PHPの標準関数で簡単に見える
    https://www.php.net/manual/ja/function.token-get-all.php

    View Slide

  16. ● 1列目 → トークン値
    ● 2列目 → トークン
    ● 3列目 → 行番号
    PHPがどう分解されていくか(字句解析編)
    ● さっきのソースを分解するとこんな感じ

    View Slide

  17. PHPがどう分解されていくか(構文解析編)
    ● さっきのトークンから、このような ASTを作って構文の妥当性を検証。
    ○ 四則演算、関数、クラス諸々が入るともはや解読不能
    https://github.com/ircmaxell/php-ast-visualizer

    View Slide

  18. PHPがどう分解されていくか (バイトコード編)
    ● 今までのステップを経てバイトコードが生成される。
    ○ Zend VMはこれを実行する。
    ←実際の命令
    php.iniでopcacheの有効化が必要
    FYI: ダンプには https://github.com/derickr/vld を使うのもおすすめ

    View Slide

  19. php-srcを
    読んでみる
    static void zend_compile_echo(zend_ast *ast)

    View Slide

  20. トークン値 シンボル名(token_name関数で取得)
    トークン値がソース内部でどう解釈されるか
    ● さっきのソースを分解するとこんな感じ
    267 -> T_INLINE_HTML
    389 -> T_OPEN_TAG
    392 -> T_WHITESPACE
    291 -> T_ECHO
    291 -> T_WHITESPACE
    291 -> T_CONSTANT_ENCAPSED_STRING

    View Slide

  21. トークン値がソース内部でどう解釈されるか
    ● さっきのソースを分解するとこんな感じ
    267 -> T_INLINE_HTML
    389 -> T_OPEN_TAG
    392 -> T_WHITESPACE
    291 -> T_ECHO
    291 -> T_WHITESPACE
    291 -> T_CONSTANT_ENCAPSED_STRING
    トークン値 シンボル名(token_name関数で取得)

    View Slide

  22. php-srcを読んでみる
    T_ECHOでgrepかけてみる

    View Slide

  23. php-srcを読んでみる
    T_ECHOでgrepかけてみる
    echoという文字を見つけたら
    T_ECHOでトークン化

    View Slide

  24. php-srcを読んでみる
    T_ECHOでgrepかけてみる
    ASTを生成

    View Slide

  25. php-srcを読んでみる
    T_ECHOでgrepかけてみる
    バイトコードを生成

    View Slide

  26. php-srcを読んでみる
    ● 今までのステップを経てバイトコードが生成される。
    ○ バイトコードから先の世界は省略します。
    ←実際の命令

    View Slide

  27. nginx編 location ~ \.php$ {
    fastcgi_pass 127.0.0.1:9000;
    }

    View Slide

  28. 流れ
    ブラウザからのリクエストをnginxが橋渡しする

    View Slide

  29. 流れ
    ブラウザからのリクエストをnginxが橋渡ししてfpmサーバへ

    View Slide

  30. 流れ
    nginx -> php-fpmの流れ
    curl http://localhost:10081(/) nginx
    nginx.conf (default.conf)
    設定ファイルで PHPファイルのパスを解決
    fpmサーバの接続先を設定
    (unixソケット指定の場合もあり)
    localhost:9000 (fpmサーバ)へ
    対象のPHPのファイル実行に
    必要な情報を伝達

    View Slide

  31. 流れ
    nginx -> php-fpmに飛んでいるリクエスト(補足)

    View Slide

  32. 流れ
    ● DOCUMENT_ROOT (nginx.confのroot) はphpのコードが動作する環
    境に合わせる。
    ● webサーバとappサーバが独立している場合は要注意。
    (コンテナ環境(docker compose/ECS) など)
    リクエスト
    nginx.conf

    View Slide

  33. 今までの流れをざっくり

    View Slide

  34. まとめ
    ● サンプルコードを用いたPHPのコード実行の流れ
    ○ PHPのトークン化 -> AST -> バイトコード生成までの流れ
    ● ブラウザからPHPのコードを実行するまでの流れ
    ○ webサーバとfpmサーバ間でやりとりする
    ○ 上記がどのように繋がって疎通しているか
    ■ 該当ソースコードの図示

    View Slide

  35. 参考
    ● PHP の echo と print の違い (闇)
    https://y-uti.hatenablog.jp/entry/2015/12/07/000027
    ● ミドルウェアのソースコードリーディングのすすめ
    https://developers.freee.co.jp/entry/how-to-read-source-code-of-middleware
    ● Zend Engine 2 オペコード
    http://php.adamharvey.name/manual/ja/internals2.opcodes.php
    ● PHP7 と HHVM/Hack 言語って何が違うの?
    https://www.infiniteloop.co.jp/tech-blog/2018/07/difference-between-php7-and-hhvm-hack/
    ● VLDでPHPのオペコードを確認する
    https://saitodev.co/article/VLD%E3%81%A7PHP%E3%81%AE%E3%82%AA%E3%83%9A%E3%82%B3%E3%83%B
    C%E3%83%89%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B
    ● 詳説ぺちぺち
    https://www.slideshare.net/do_aki/ss-11304937
    ● PHP AST 徹底解説
    https://www.slideshare.net/do_aki/php-ast
    ● JIT のコードを読んでみた
    https://www.slideshare.net/y-uti/jit-70023246
    ● 第9章 速習yacc
    https://i.loveruby.net/ja/rhg/book/yacc.html
    ありがとうございました!

    View Slide

  36. おわり

    View Slide