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
53
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
790
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
苦しいTiDBへの移行を乗り越えて快適な運用を目指す
leveragestech
0
560
Rubyで始める関数型ドメインモデリング
shogo_tksk
0
100
GAEログのコスト削減
mot_techtalk
0
120
Immutable ActiveRecord
megane42
0
140
『GO』アプリ データ基盤のログ収集システムコスト削減
mot_techtalk
0
120
CNCF Project の作者が考えている OSS の運営
utam0k
6
710
Conform を推す - Advocating for Conform
mizoguchicoji
3
690
GitHub Actions × RAGでコードレビューの検証の結果
sho_000
0
260
TokyoR116_BeginnersSession1_環境構築
kotatyamtema
0
110
JavaScriptツール群「UnJS」を5分で一気に駆け巡る!
k1tikurisu
9
1.8k
XStateを用いた堅牢なReact Components設計~複雑なClient Stateをシンプルに~ @React Tokyo ミートアップ #2
kfurusho
1
900
データベースのオペレーターであるCloudNativePGがStatefulSetを使わない理由に迫る
nnaka2992
0
140
Featured
See All Featured
A Modern Web Designer's Workflow
chriscoyier
693
190k
A designer walks into a library…
pauljervisheath
205
24k
Building Adaptive Systems
keathley
40
2.4k
Fashionably flexible responsive web design (full day workshop)
malarkey
406
66k
Statistics for Hackers
jakevdp
797
220k
4 Signs Your Business is Dying
shpigford
182
22k
The Pragmatic Product Professional
lauravandoore
32
6.4k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
49
2.3k
Thoughts on Productivity
jonyablonski
69
4.5k
Facilitating Awesome Meetings
lara
52
6.2k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.3k
Embracing the Ebb and Flow
colly
84
4.6k
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!