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
84
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
71
PHP Internals わいわい #1 の資料
youkidearitai
PRO
1
1.3k
mb_trim関数を作りました
youkidearitai
PRO
1
960
PHPの次期バージョンはこの時期どうなっているのか - Internalsの開発体制について - PHPカンファレンス小田原
youkidearitai
PRO
1
800
文字とはなにか - PHPの文字コード処理について - PHP Lovers Meetup #5
youkidearitai
PRO
1
290
はじめてのOSSコントリビュート
youkidearitai
PRO
11
4.3k
文字とはなにか - PHPの文字コード処理について -
youkidearitai
PRO
0
840
現在のmbstringの立ち位置 これからどうなっていくのか
youkidearitai
PRO
0
410
PHP 8.3のmbstringの進化を見てください - コントリビューターとしてのかかわり -
youkidearitai
PRO
0
1.4k
Other Decks in Programming
See All in Programming
WebViewの現在地 - SwiftUI時代のWebKit - / The Current State Of WebView
marcy731
0
110
イベントストーミング図からコードへの変換手順 / Procedure for Converting Event Storming Diagrams to Code
nrslib
1
570
Webの外へ飛び出せ NativePHPが切り拓くPHPの未来
takuyakatsusa
2
460
新メンバーも今日から大活躍!SREが支えるスケールし続ける組織のオンボーディング
honmarkhunt
1
420
Kotlin エンジニアへ送る:Swift 案件に参加させられる日に備えて~似てるけど色々違う Swift の仕様 / from Kotlin to Swift
lovee
1
260
PHPで始める振る舞い駆動開発(Behaviour-Driven Development)
ohmori_yusuke
2
240
童醫院敏捷轉型的實踐經驗
cclai999
0
210
LT 2025-06-30: プロダクトエンジニアの役割
yamamotok
0
660
プロダクト志向なエンジニアがもう一歩先の価値を目指すために意識したこと
nealle
0
120
Composerが「依存解決」のためにどんな工夫をしているか #phpcon
o0h
PRO
1
250
AI時代のソフトウェア開発を考える(2025/07版) / Agentic Software Engineering Findy 2025-07 Edition
twada
PRO
7
310
20250704_教育事業におけるアジャイルなデータ基盤構築
hanon52_
4
250
Featured
See All Featured
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.9k
Documentation Writing (for coders)
carmenintech
72
4.9k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
30
2.1k
It's Worth the Effort
3n
185
28k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
44
2.4k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Optimising Largest Contentful Paint
csswizardry
37
3.3k
Automating Front-end Workflow
addyosmani
1370
200k
The Cult of Friendly URLs
andyhume
79
6.5k
Code Review Best Practice
trishagee
69
18k
Why You Should Never Use an ORM
jnunemaker
PRO
58
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!