Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
List とは何か? / PHPerKaigi 2025
Search
meihei
March 28, 2025
Programming
1.9k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
List とは何か? / PHPerKaigi 2025
https://fortee.jp/phperkaigi-2025/proposal/04d840aa-6baa-4f57-8d63-54e4f446e069
meihei
March 28, 2025
More Decks by meihei
See All by meihei
隙間ツール開発のすすめ / PHP Conference Fukuoka 2025
meihei3
0
1.4k
QRコードを学んで遊ぼう / php-study-177
meihei3
0
260
改めて学ぶ Trait の使い方 / phpcon odawara 2025
meihei3
1
2.1k
WebアプリケーションにおけるPDOの使い方入門 / phpcon odawara 2024
meihei3
3
2.8k
PHPerライフをChrome拡張開発でちょっと便利に / PR TIMES x DMM.com
meihei3
0
500
ファイルを選択してZIPダウンロードする機能ってどうやって作るの? / phpcondo 2023
meihei3
1
960
New Relic CodeStreamを 使って、エラーを 加速的迅速に改修しよう! #NRUG Vol.8
meihei3
0
460
PHP8.2から見る、2つの配列 / PHP Conference Japan 2023
meihei3
0
2.7k
良いコードを書く 〜10年後のPR TIMESを作る〜 / LT会 in #PRTIMES_HACKATHON 2023
meihei3
2
300
Other Decks in Programming
See All in Programming
手動確認はもう限界 〜XCUITestでCustom URL Schemeの遷移を起動種別ごとに自動テストする〜 / Testing Custom URL Schemes with XCUITest
otouto
0
370
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
200
iOSDC Japan 2026 - Swiftで作って学ぼう!データベース自作入門
kaseken
2
410
GemmaをJevのように使ってみる / Use Gemma like Jev
kishida
4
450
AWS CDKのカスタムリソースでContinuum(旧Security Agent)を実装した話 | Implementing Continuum (formerly Security Agent) via AWS CDK Custom Resource
akihisaikeda
1
110
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
450
カツオ、ご期待ください
suneo3476
0
130
AWSに止められる覚悟してますか?
morizo_1984
2
490
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
230
UnityでSystem.Net.WebSocketsなWebSocketサーバが動かないのでUnity Monoのコードを覗いてみた / about implementing websocket server with unity mono
drumath2237
1
510
設計次第でAIコードの読む量は減らせる / designing-for-code-reading
minodriven
30
13k
コードレビューのボトルネックを"する側"と"される側"の両面から解消する
yub0n
1
1.1k
Featured
See All Featured
Everyday Curiosity
cassininazir
0
340
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
540
Writing Fast Ruby
sferik
630
63k
AI: The stuff that nobody shows you
jnunemaker
PRO
10
1.1k
Raft: Consensus for Rubyists
vanstee
142
7.7k
Balancing Empowerment & Direction
lara
6
1.3k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
720
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.2k
Exploring anti-patterns in Rails
aemeredith
4
520
Making the Leap to Tech Lead
cromwellryan
135
10k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
Tell your own story through comics
letsgokoyo
1
1.1k
Transcript
© 2012-2025 BASE, Inc. 1 #phperkaigi #a List とは何か? PHPerKaigi
2025(2025/03/23)
© 2012-2025 BASE, Inc. 2 © 2012-2025 BASE, Inc. 2
これだけ覚えて帰ってください
© 2012-2025 BASE, Inc. 3 #phperkaigi #a リスト(List)とは キーが0から始まる 連続した整数である配列
© 2012-2025 BASE, Inc. 4 #phperkaigi #a 自己紹介 meihei |
Yohei Ema BASE株式会社 BASE / Product Dev / Feature Dev 1 X: @app1e_s mixi2: @meihei2 GitHub: @meihei3
© 2012-2025 BASE, Inc. 5 1 2 3 #phperkaigi #a
仕様から見たリスト 静的解析ツールから見たリスト PHPの処理から見たリスト 3つの視点からお話しします
© 2012-2025 BASE, Inc. 6 © 2012-2025 BASE, Inc. 6
仕様から見たリスト
© 2012-2025 BASE, Inc. 7 #phperkaigi #a 配列がリストである = array_is_list()
が TRUE である
© 2012-2025 BASE, Inc. 8 #phperkaigi #a RFC を読むと •
PHP RFC: Add array_is_list(array $array): bool • リスト型を導入するわけではなく、配列が0から始まる連続した整数キーで あるかどうかを判定する関数を追加するだけ • (背景)PHPの配列は、整数キーと文字列キーの両方を持つことができ、 かつその順序が保証されている ◦ [0 => 0, 1 => 1, 2 => 2] と [0 => 0, 2 => 2, 1 => 1] は異なる • (使用例)エンコーダなどで効率的にリストを判定したい時に使う ◦ [0 => 0, 1 => 1, 2 => 2] ならば ‘[0, 1, 2]’ に ◦ [0 => 0, 2 => 2, 1 => 1] ならば ‘{“0”: 0, “2”: 2, “1”: 1}’ に
© 2012-2025 BASE, Inc. 9 #phperkaigi #a 配列がリストである例 ['りんご', 'みかん',
'バナナ'] キーをすべて省略した配列 [0 => 'りんご', 1 => 'みかん', 2 => 'バナナ'] キーが0から始まる連続した整数を明 示的にした配列 [false => 'りんご', true => 'みかん', '2' => 'バナナ'] キーが0から始まる連続した整数とみ なせる値の配列 [] 空配列 ['りんご', 1, 2, null, []] 値が何であっても、キーがリストであ る要件をみたす配列
© 2012-2025 BASE, Inc. 10 #phperkaigi #a 配列がリストではない例 [1 =>
'みかん', 2 => 'バナナ'] 連続した整数キーが0から始まらない 配列 ['りんご', 'みかん', 99 => 'かまぼこ'] 整数キー連続していない配列 ['a' => 'apple', 'b' => 'banana'] キーが整数ではない文字列の配列
© 2012-2025 BASE, Inc. 11 #phperkaigi #a リストを返す配列関数(よく使うもの) array_keys, array_values,
range 常にリストを返す array_chunk preserve_keys が false ならリスト を返す array_column index_key を指定しないならリストを 返す array_merge, array_map, array_slice, array_reverse 入力がリストならリストを返す
© 2012-2025 BASE, Inc. 12 #phperkaigi #a 配列がリストであるかは array_is_list() を使って
実行時に判定する
© 2012-2025 BASE, Inc. 13 #phperkaigi #a 関数呼び出し時にリストか判定する $a =
[ 0 => 'りんご', 3 => 'ぶどう', 1 => 'みかん', 2 => 'バナナ', ]; echo array_is_list($a); // FALSE unset($a[3]); echo array_is_list($a); // TRUE 1回目の呼び出し時は、キーが 0,3,1,2 の順になるからリストではな い。 2回目の呼び出し時は、キーが 0,1,2 の順になるからリストとなる。
© 2012-2025 BASE, Inc. 14 © 2012-2025 BASE, Inc. 14
静的解析ツールから見たリスト
© 2012-2025 BASE, Inc. 15 #phperkaigi #a 配列がリストである = list<T>
で表される配列
© 2012-2025 BASE, Inc. 16 #phperkaigi #a リスト型 • PHPの仕様上、リスト型は無い
• 静的解析ツールではPHPDoc上で扱う擬似的な型としてリスト型がある • list<T> は array<int, T> のサブタイプとして定義される ◦ list<T> は、配列が array<int, T> であることに加えて、キーが0から始まる連続し た整数である配列 • 配列がリストであるかを、より厳格に型としてチェックできる
© 2012-2025 BASE, Inc. 17 #phperkaigi #a 静的解析ツールによる型チェック /** *
@param list<string> $x **/ function hello(array $x): void {...} $a = ['りんご', 'みかん', 99 => 'かまぼこ']; hello($a); // Error: Parameter #1 $x of function hello expects list<string>, array{0: 'りんご', 1: ' みかん', 99: 'かまぼこ'} given. PHPを実行する分にはエラーは発生し ない。 静的解析ツールを使うと、厳格に配列 とリストを区別するので、エラーが発 生する(PHPStan Level 5)。
© 2012-2025 BASE, Inc. 18 #phperkaigi #a インライン @var タグもチェックする
/** @var list<string> $a **/ $a = [ 0 => 'りんご', 1 => 'みかん', 99 => 'かまぼこ', ]; // Error: PHPDoc tag @var with type list<string> is not subtype of native type array{0: 'りんご', 1: 'みかん', 99: 'かまぼこ'}. コードの途中でローカル変数を定義す る場合でも、list<T> 型をチェックし てくれる(PHPStan 1.10, Level 2)。 以前は負の整数のキーに非対応だった が、つい先々週修正された。 phpstan/phpstan#12708 phpstan/phpstan-src#3870
© 2012-2025 BASE, Inc. 19 © 2012-2025 BASE, Inc. 19
PHPの処理から見たリスト
© 2012-2025 BASE, Inc. 20 #phperkaigi #a Packed Array かつ空き領域
(holes)を含んでいない配列 ならば 配列がリストである
© 2012-2025 BASE, Inc. 21 #phperkaigi #a PHPの配列は2つある Hash Table
• キーからハッシュ表を 使ってデータアクセス する • 連想配列を実装する Packed Array • 純粋な配列としてデータ アクセスする • メモリ効率が良く処理が高速
© 2012-2025 BASE, Inc. 22 #phperkaigi #a Packed Array とリスト
• Packed Array は、配列のキーが0から始まる連続した整数である時に 自動的に最適化された配列の内部構造 • 基本的にはリストと条件が同じである • しかし、unset などで空き領域(holes)が生まれることがある ◦ その場合も Packed Array では在り続けるので、Packed Array だけどリストではな い状態が生まれる。 • Packed Array から Hash Table へ自動的に変更されることはあるが、 Hash Table から Packed Array への自動的な変更されることはない ◦ リストだけど Packed Array ではない(Hash Table である)状態が存在する 参照: PHP8.2から見る、2つの配列 / PHP Conference Japan 2023 https://speakerdeck.com/meihei3/php-conference-japan-2023
© 2012-2025 BASE, Inc. 23 #phperkaigi #a 配列がリストである多くの場合 // Packed
Array $a = ['りんご', 'みかん', 'バナナ']; echo array_is_list($a); // TRUE 配列のキーが0から始まる連続した整 数であるので、自動的に Packed Array として最適化される。 この状態はメモリ効率が良くて、処理 も高速。
© 2012-2025 BASE, Inc. 24 #phperkaigi #a Packed Array だがリストではない場合
// Packed Array $a = ['りんご', 'みかん', 'バナナ']; unset($a[1]); echo array_is_list($a); // FALSE unset で要素を削除されただけでは、 Hash Table への自動的な変更は行わ れない。 ただ空き領域が生まれる。
© 2012-2025 BASE, Inc. 25 #phperkaigi #a リストだが Packed Array
ではない場合 // Hash Table $a = [ 0 => 'りんご', 3 => 'ぶどう', 1 => 'みかん', 2 => 'バナナ', ]; unset($a[3]); echo array_is_list($a); // TRUE 配列のキーが連番となっていないの で、Hash Table となる。 配列の再生成が行われない限り、 Packed Array から Hash Table へ自 動的に変更されることはない。
© 2012-2025 BASE, Inc. 26 #phperkaigi #a まとめ • リストとは、キーが0から始まる連続した整数である配列
• PHPの仕様では、リスト型は存在せず array_is_list が TRUE で ある配列のことをリストと言う • 静的解析ではリストを list<T> 型として表現する • 内部実装では Packed Array かつ空き領域(holes)を含んでいない配列な らば、配列がリストである • 多くの場合ではリストは高速でメモリ効率も良い • みんなリストを使おう!
© 2012-2025 BASE, Inc. 27 #phperkaigi #a We are hiring!
https://binc.jp/jobs