Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
PHP Internals わいわい #3 mb_*関数を作ってみよう
Search
てきめん tekimen
PRO
December 22, 2024
Programming
0
55
PHP Internals わいわい #3 mb_*関数を作ってみよう
本来はPHPカンファレンス2024で発表する予定の資料でしたが、体調不良で参加できなかったため作成しました。
てきめん tekimen
PRO
December 22, 2024
Tweet
Share
More Decks by てきめん tekimen
See All by てきめん tekimen
Windows版php-srcデバッグ方法
youkidearitai
PRO
1
51
PHP Internals わいわい #1 の資料
youkidearitai
PRO
1
1.2k
mb_trim関数を作りました
youkidearitai
PRO
1
800
PHPの次期バージョンはこの時期どうなっているのか - Internalsの開発体制について - PHPカンファレンス小田原
youkidearitai
PRO
1
680
文字とはなにか - PHPの文字コード処理について - PHP Lovers Meetup #5
youkidearitai
PRO
1
250
はじめてのOSSコントリビュート
youkidearitai
PRO
11
3.7k
文字とはなにか - PHPの文字コード処理について -
youkidearitai
PRO
0
740
現在のmbstringの立ち位置 これからどうなっていくのか
youkidearitai
PRO
0
260
PHP 8.3のmbstringの進化を見てください - コントリビューターとしてのかかわり -
youkidearitai
PRO
0
1.3k
Other Decks in Programming
See All in Programming
Amazon Q Developer Proで効率化するAPI開発入門
seike460
PRO
0
110
動作確認やテストで漏れがちな観点3選
starfish719
6
1k
Boost Performance and Developer Productivity with Jakarta EE 11
ivargrimstad
0
330
ファインディLT_ポケモン対戦の定量的分析
fufufukakaka
0
740
pylint custom ruleで始めるレビュー自動化
shogoujiie
0
120
Writing documentation can be fun with plugin system
okuramasafumi
0
120
密集、ドキュメントのコロケーション with AWS Lambda
satoshi256kbyte
0
190
Grafana Cloudとソラカメ
devoc
0
170
XStateを用いた堅牢なReact Components設計~複雑なClient Stateをシンプルに~ @React Tokyo ミートアップ #2
kfurusho
1
910
『GO』アプリ データ基盤のログ収集システムコスト削減
mot_techtalk
0
130
Introduction to kotlinx.rpc
arawn
0
700
Honoをフロントエンドで使う 3つのやり方
yusukebe
7
3.3k
Featured
See All Featured
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
21
2.5k
Adopting Sorbet at Scale
ufuk
74
9.2k
Fontdeck: Realign not Redesign
paulrobertlloyd
83
5.4k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
160
15k
Optimising Largest Contentful Paint
csswizardry
34
3.1k
It's Worth the Effort
3n
184
28k
How STYLIGHT went responsive
nonsquared
98
5.4k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.2k
Documentation Writing (for coders)
carmenintech
67
4.6k
Java REST API Framework Comparison - PWX 2021
mraible
28
8.4k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
45
9.4k
Transcript
PHP Internals わいわい mb_*関数を作ってみよう!
自己紹介 てきめん • 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 オレ
アジェンダ • まずはPHPをコンパイル! • mbstring拡張について内部構造の解説 • mb_*関数の検討 • 作成 •
テスト
趣旨 • PHP Internals Bookを元に、PHPのソースコード、php-srcを 取得、コンパイルしたりソースコードを読みます – https://www.phpinternalsbook.com/ – あわよくばバグを見つけたら報告したり
– あわよくばテストコードを修正したり – 更に行けば関数・機能を追加するとか • PHP Internalに向かって新機能を追加する提案をしたりで きないかと思っています
コンパイルの前段階 • Linuxを用意します • 今回はDockerを使います – WSLやmultipass、limaなどを使ってもらっても構いま せん
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
PHPのコンパイルの準備 # cd php-src # ./buildconf -f # ./configure --enable-debug
--enable-mbstring # make # make test # make install # --prefix を指定していないので/usr/local/に入る # php -v #これで実行できる!
この状態を保存します • Command + p + qで抜けるか、もしくは別のコンソー ルを開いてください • >
docker ps で開いているContainer IDを調べます • > docker commit [container id] ubuntu:php85 – このようにすればubuntu:php85で今までの作業した内容 を保存して、コンパイルできた状態で入れます
このようにコンテナを作れました > 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
tips • 今回はDockerを使いましたが、LinuxやmacOS内 部で複数のPHPを持ちたいときは --prefix オプ ションが便利です。 – --prefix=$HOME/php84 とかしてあげると、ホームディ
レクトリ配下にバージョンごとにコンパイル・インストー ルができるわけです。
デバッグ手法 • Linuxではgdbとかlldbなどが使えますが、今回はgdb を使います • コンテナ内部でvimとctagsなどを利用してソースコー ドを読みます – 手元でコンパイルできるとVisual Studio
Codeがつかえた りするようですね • https://php.github.io/php-src/introduction/ides/visual-studi o-code.html – このあたり知ってる人は共有してくれると嬉しい
開発環境を揃える # apt install exuberant-ctags vim # cd ~/php-src #
ctags -R . # カレントディレクトリが/root/php-src
コンパイルオプションあれこれ 変数 CC をつけるとコンパイラを指定できます 変数 CFLAGS でコンパイルオプションを指定できま す 例: CC=clang
CFLAGS=”-g” ./configure –enable- debug # clangでコンパイルし、-gオプションを加え られます
テストについて 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拡張のみテストする
いざmbstring関数の実装へ • これで準備はおわりました • mbstring関数の実装をしていきましょう – mb_my_function関数を作ります • 仕様として、「最初の1文字を取り除いてEUC-JPに変換する」 としましょう
どうしてmbstringか • CJK(China, Japan, Korea)ユーザーはこの拡張に とてもお世話になります • 母国語を日本語とする我々はPHPのアドバンテー ジがここにあります •
mbstringへのコントリビュートがPHPへのコントリ ビュートの近道だと考えています
関数の作成 • 今回のゴールは関数の作成です • まずは関数の作り方を学びます • mbstringで関数を作るので、ext/mbstringに作業 します。ただし、カレントディレクトリはphp-srcのトッ プディレクトリです –
ctagsで作ったtagsファイルでジャンプしたいため
stubファイルを編集しスタブを追加
スタブを追加
関数を書きます ext/mbstring/mbstring.cを編集します。 まずは引数を取り、何もしない関数を作りま す。 引数はZEND_PARSE_PARAMETERS_START、 ZEND_PARSE_PARAMETERS_ENDで囲みま す。 $encodingが不正な場合は例外をスローしてい ます。
mbstringのルール • 内部ではUTF-32で動いています(UCS方式) – たとえば、Shift_JISからEUC-JPでは • Shift_JIS → UTF-32 →
EUC-JP となります – データ型はuint32_tで取ります • 32bit(4byte)ですね
内部で使える関数 • mb_get_strlen – mb_strlenの内部実装関数です。 • mb_get_substr – mb_substrの内部実装関数です。 •
mb_fast_convert – mb_convert_encodingの内部実装関数です。 • mb_fast_convert関数で内部でUTF-32に変換して目的の文字エンコー ディングに変換しています、これがUCS方式
mb_fast_convertの実装 338行目でUTF-32 に変換し、341行目 でUTF-32から目的 のエンコーディン グに変換している
mb_get_strlenの実装 mb_fast_strlen_ utf8は難しいので 読まなくていい to_wcharメソッド がコードポイント長 を返すので、それを 足して返す実装に なってる
中身を作ります まず、 mb_get_substrで 1文字だけ取り除き ます。長さは短い 方を取ってくれま す。 次に、 mbfl_name2enco dingでEUC-JPのイ
ンスタンスを取 得、 mb_fast_convert 関数で変換、 retを開放で終わり
動作確認 ハローワールドという文字列から、最初の1文字を抜き取ってEUC-JPに変換すること に成功しました! 出力の確認でmb_convert_encodingを挟んでいますが、mbstringのお作法がちょっ とでもわかると嬉しいです
テストの作成 • テストを書きま しょう • ext/mbstring/ tests/ mb_my_functio n.phpt に作成し
ます
テストの実行 sapi/cli/php run-tests.php -P ext/mbstring/tests/mb_my_fun ction.phpt これで実行してPASS を確認します。
さらなる冒険へ • これはちょっと高レベルな世界かと思われます • もっと実装の方に行くと、さらなる知見が得られると 思います • でも、既存のコードで新しい関数を開発することは 可能ですから、色々いじってみてください
おわり • 今回はmb_my_function関数を作り、変換と substrを体験しました • これだけでもちゃんと新しい関数が作れますが、C 言語の知識ともっとmbstringのソースコードの探 求をすると効率の良いコードが書けます • Enjoy!