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
66
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
62
PHP Internals わいわい #1 の資料
youkidearitai
PRO
1
1.2k
mb_trim関数を作りました
youkidearitai
PRO
1
860
PHPの次期バージョンはこの時期どうなっているのか - Internalsの開発体制について - PHPカンファレンス小田原
youkidearitai
PRO
1
730
文字とはなにか - PHPの文字コード処理について - PHP Lovers Meetup #5
youkidearitai
PRO
1
270
はじめてのOSSコントリビュート
youkidearitai
PRO
11
4k
文字とはなにか - PHPの文字コード処理について -
youkidearitai
PRO
0
780
現在のmbstringの立ち位置 これからどうなっていくのか
youkidearitai
PRO
0
360
PHP 8.3のmbstringの進化を見てください - コントリビューターとしてのかかわり -
youkidearitai
PRO
0
1.3k
Other Decks in Programming
See All in Programming
Boost Your Performance and Developer Productivity with Jakarta EE 11
ivargrimstad
0
290
今から始めるCursor / Windsurf / Cline
kengo_hayano
0
110
SLI/SLOの設定を進めるその前に アラート品質の改善に取り組んだ話
tanden
2
740
PHPでお金を扱う時、終わりのない 謎の1円調査の旅にでなくて済む方法
nakka
4
1.4k
DataStoreをテストする
mkeeda
0
160
自分のために作ったアプリが、グローバルに使われるまで / Indie App Development Lunch LT
pixyzehn
1
130
安全に倒し切るリリースをするために:15年来レガシーシステムのフルリプレイス挑戦記
sakuraikotone
5
2.4k
Go1.24 go vetとtestsアナライザ
kuro_kurorrr
2
490
Return of the Full-Stack Developer
simas
PRO
1
320
爆速スッキリ! Rspack 移行の成果と道のり - Muddy Web #11
dora1998
1
160
アプリを起動せずにアプリを開発して品質と生産性を上げる
ishkawa
0
450
いまさら聞けない生成AI入門: 「生成AIを高速キャッチアップ」
soh9834
12
3.9k
Featured
See All Featured
Speed Design
sergeychernyshev
28
870
Java REST API Framework Comparison - PWX 2021
mraible
29
8.5k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
233
17k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
60k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
8
700
Build your cross-platform service in a week with App Engine
jlugia
229
18k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
4
480
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
22
2.6k
Navigating Team Friction
lara
184
15k
GraphQLの誤解/rethinking-graphql
sonatard
70
10k
Bash Introduction
62gerente
611
210k
Building Applications with DynamoDB
mza
94
6.3k
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!