Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
PHP Internals わいわい mb_*関数を作ってみよう!
Slide 2
Slide 2 text
自己紹介 てきめん ● https://tekitoh-memdhoi.info ● X: @youkidearitai ● https://github.com/youkidearitai ● PHP 8.4で複数の関数を作りました – mb_trim, mb_ltrim, mb_rtrim – mb_ucfirst, mb_lcfirst – grapheme_str_split オレ
Slide 3
Slide 3 text
アジェンダ ● まずはPHPをコンパイル! ● mbstring拡張について内部構造の解説 ● mb_*関数の検討 ● 作成 ● テスト
Slide 4
Slide 4 text
趣旨 ● PHP Internals Bookを元に、PHPのソースコード、php-srcを 取得、コンパイルしたりソースコードを読みます – https://www.phpinternalsbook.com/ – あわよくばバグを見つけたら報告したり – あわよくばテストコードを修正したり – 更に行けば関数・機能を追加するとか ● PHP Internalに向かって新機能を追加する提案をしたりで きないかと思っています
Slide 5
Slide 5 text
コンパイルの前段階 ● Linuxを用意します ● 今回はDockerを使います – WSLやmultipass、limaなどを使ってもらっても構いま せん
Slide 6
Slide 6 text
PHPのコンパイルの準備 > docker pull ubuntu:22.04 > docker run -it ubuntu:22.04 bash # apt update && apt install -y pkg-config build- essential autoconf bison re2c libxml2-dev libsqlite3-dev gdb git libonig-dev # cd ~ # /root # git clone https://github.com/php/php-src
Slide 7
Slide 7 text
PHPのコンパイルの準備 # cd php-src # ./buildconf -f # ./configure --enable-debug --enable-mbstring # make # make test # make install # --prefix を指定していないので/usr/local/に入る # php -v #これで実行できる!
Slide 8
Slide 8 text
この状態を保存します ● Command + p + qで抜けるか、もしくは別のコンソー ルを開いてください ● > docker ps で開いているContainer IDを調べます ● > docker commit [container id] ubuntu:php85 – このようにすればubuntu:php85で今までの作業した内容 を保存して、コンパイルできた状態で入れます
Slide 9
Slide 9 text
このようにコンテナを作れました > docker run -it ubuntu:php85 root@ea6b72b5f128:/# php -v PHP 8.4.0-dev (cli) (built: May 31 2024 00:57:46) (NTS DEBUG) Copyright (c) The PHP Group Zend Engine v4.4.0-dev, Copyright (c) Zend Technologies
Slide 10
Slide 10 text
tips ● 今回はDockerを使いましたが、LinuxやmacOS内 部で複数のPHPを持ちたいときは --prefix オプ ションが便利です。 – --prefix=$HOME/php84 とかしてあげると、ホームディ レクトリ配下にバージョンごとにコンパイル・インストー ルができるわけです。
Slide 11
Slide 11 text
デバッグ手法 ● Linuxではgdbとかlldbなどが使えますが、今回はgdb を使います ● コンテナ内部でvimとctagsなどを利用してソースコー ドを読みます – 手元でコンパイルできるとVisual Studio Codeがつかえた りするようですね ● https://php.github.io/php-src/introduction/ides/visual-studi o-code.html – このあたり知ってる人は共有してくれると嬉しい
Slide 12
Slide 12 text
開発環境を揃える # apt install exuberant-ctags vim # cd ~/php-src # ctags -R . # カレントディレクトリが/root/php-src
Slide 13
Slide 13 text
コンパイルオプションあれこれ 変数 CC をつけるとコンパイラを指定できます 変数 CFLAGS でコンパイルオプションを指定できま す 例: CC=clang CFLAGS=”-g” ./configure –enable- debug # clangでコンパイルし、-gオプションを加え られます
Slide 14
Slide 14 text
テストについて https://www.phpinternalsbook.com/tests/runni ng_the_test_suite.html # sapi/cli/php run-tests.php # すべてのテストを行 う # sapi/cli/php run-tests.php -P ext/mbstring # mbstring拡張のみテストする
Slide 15
Slide 15 text
いざmbstring関数の実装へ ● これで準備はおわりました ● mbstring関数の実装をしていきましょう – mb_my_function関数を作ります ● 仕様として、「最初の1文字を取り除いてEUC-JPに変換する」 としましょう
Slide 16
Slide 16 text
どうしてmbstringか ● CJK(China, Japan, Korea)ユーザーはこの拡張に とてもお世話になります ● 母国語を日本語とする我々はPHPのアドバンテー ジがここにあります ● mbstringへのコントリビュートがPHPへのコントリ ビュートの近道だと考えています
Slide 17
Slide 17 text
関数の作成 ● 今回のゴールは関数の作成です ● まずは関数の作り方を学びます ● mbstringで関数を作るので、ext/mbstringに作業 します。ただし、カレントディレクトリはphp-srcのトッ プディレクトリです – ctagsで作ったtagsファイルでジャンプしたいため
Slide 18
Slide 18 text
stubファイルを編集しスタブを追加
Slide 19
Slide 19 text
スタブを追加
Slide 20
Slide 20 text
関数を書きます ext/mbstring/mbstring.cを編集します。 まずは引数を取り、何もしない関数を作りま す。 引数はZEND_PARSE_PARAMETERS_START、 ZEND_PARSE_PARAMETERS_ENDで囲みま す。 $encodingが不正な場合は例外をスローしてい ます。
Slide 21
Slide 21 text
mbstringのルール ● 内部ではUTF-32で動いています(UCS方式) – たとえば、Shift_JISからEUC-JPでは ● Shift_JIS → UTF-32 → EUC-JP となります – データ型はuint32_tで取ります ● 32bit(4byte)ですね
Slide 22
Slide 22 text
内部で使える関数 ● mb_get_strlen – mb_strlenの内部実装関数です。 ● mb_get_substr – mb_substrの内部実装関数です。 ● mb_fast_convert – mb_convert_encodingの内部実装関数です。 ● mb_fast_convert関数で内部でUTF-32に変換して目的の文字エンコー ディングに変換しています、これがUCS方式
Slide 23
Slide 23 text
mb_fast_convertの実装 338行目でUTF-32 に変換し、341行目 でUTF-32から目的 のエンコーディン グに変換している
Slide 24
Slide 24 text
mb_get_strlenの実装 mb_fast_strlen_ utf8は難しいので 読まなくていい to_wcharメソッド がコードポイント長 を返すので、それを 足して返す実装に なってる
Slide 25
Slide 25 text
中身を作ります まず、 mb_get_substrで 1文字だけ取り除き ます。長さは短い 方を取ってくれま す。 次に、 mbfl_name2enco dingでEUC-JPのイ ンスタンスを取 得、 mb_fast_convert 関数で変換、 retを開放で終わり
Slide 26
Slide 26 text
動作確認 ハローワールドという文字列から、最初の1文字を抜き取ってEUC-JPに変換すること に成功しました! 出力の確認でmb_convert_encodingを挟んでいますが、mbstringのお作法がちょっ とでもわかると嬉しいです
Slide 27
Slide 27 text
テストの作成 ● テストを書きま しょう ● ext/mbstring/ tests/ mb_my_functio n.phpt に作成し ます
Slide 28
Slide 28 text
テストの実行 sapi/cli/php run-tests.php -P ext/mbstring/tests/mb_my_fun ction.phpt これで実行してPASS を確認します。
Slide 29
Slide 29 text
さらなる冒険へ ● これはちょっと高レベルな世界かと思われます ● もっと実装の方に行くと、さらなる知見が得られると 思います ● でも、既存のコードで新しい関数を開発することは 可能ですから、色々いじってみてください
Slide 30
Slide 30 text
おわり ● 今回はmb_my_function関数を作り、変換と substrを体験しました ● これだけでもちゃんと新しい関数が作れますが、C 言語の知識ともっとmbstringのソースコードの探 求をすると効率の良いコードが書けます ● Enjoy!