Skip to content

なぜPHPに型がつくのか

公開日:

栃木県小山市小山市立 生涯学習センター ギャラリーで開催された『TechGYOZA 2025』でライトニングトーク(5分)として発表しました。

Download PDF

スライドテキスト

Page 1

なぜPHPに型がつくのか

All Your PHP Code Are Typed by Us

pixiv Inc.

USAMI Kenta

2025-12-13 #TechGyoza小山市立 生涯学習センター ギャラリー

Page 2

お前誰よ

  • うさみけんた (@tadsan) / Zonu.EXE / にゃんだーすわん
  • ピクシブ株式会社 Platform Div > WebTechnology Team PHPer
  • 2012年末から現職、APIとかCIとかいろいろなところを見つめてきました
  • 最近チームが再編されてインフラっぽい仕事もしてます
  • Emacs PHP Modeを開発しています (2017年-)
  • プログラミング言語にちょっとこだわりのある素人 (spcamp2010)

Page 3

Page 4

Page 5

PHPcon新潟

Page 6

PHPcon新潟

PHPcon広島

Page 7

TechRAMEN

PHPcon新潟

PHPcon広島

Page 8

趣味はプログラミング言語

Page 9

特に動的言語/スクリプト言語が好き

Page 10

動的言語には無限の可能性()があります

Page 11

さて

Page 12

近年の流れ

Page 13

2000年代は動的言語が大活躍した時代

Page 14

重厚なIDE…長大なコンパイル時間…

Page 15

スクリプト言語はシンプルなエディタで簡単に書ける!

Page 16

2000年前後CGIで簡単にWebアプリが書ける

Page 17

2010年前後Railsで高機能なものが簡単に書ける

Page 18

アプリケーションが大規模に「育つ」と収拾がつかなくなってくる

Page 19

メソッドの実装をわざわざ探してコードを読まなければ引数の種類すらわからん

Page 20

……

Page 21

202x年世界は型の炎に包まれた!

Page 22

JavaScript

Page 23

JavaScript

↓TypeScript

Page 24

Python

Page 25

Python

↓typing module

Page 26

Ruby

Page 27

Ruby

↓Inline RBS

Page 28

海は枯れ、地は裂け、全ての型なしが死滅したかのように見えた

Page 29

だが、PHPは死滅していなかった!

Page 30

世紀末救世主伝説

<?php

Page 31

誰でも簡単にホームページが作れるゆるふわ言語

Page 32

PHPについてのパブリックイメージ

脆弱性 ゆるふわ 弱い型 動的クソザコ 型なし 意味不明 弱い自動変換 貧弱 Perlっぽい 適当

Page 33

PHPについての認識は概ね間違い

脆弱性 ゆるふわ 弱い型 動的クソザコ 型なし 意味不明 弱い自動変換 貧弱 Perlっぽい 適当

Page 34

認識を揃えておきましょう

Page 35

動的言語/スクリプト言語

  • 実行時の宣言、evalなどプログラム自身を操作対象としながら実行できがち
  • スクリプト/インタプリタなどの特徴は直交する概念だが、結びつきがち
  • 関数・変数に静的な型がついてない言語でしょ、という回答は30点くらい
  • C#はいわゆる静的型付きの言語だが、dynamicとして動的な機能も提供

Page 36

言語としてのPHP

  • よくあるC言語風の制御構文と標準関数をもったスクリプト言語
  • if, else, switch, while, for, goto
  • PHPのgotoは綺麗なgoto
  • 関数定義、クラス定義(class, interface, trait, enum)
  • クラスや関数の再定義(オープンクラス・モンキーパッチ)はできない

Page 37

動的言語でも型を書くことが広まってきた

Page 38

ドキュメントとしての型

Page 39

function add($a, $b) {return $a + $b;}

Page 40

/*** @param int $a* @param int $b* @return int|float*/

function add($a, $b) {return $a + $b;}

Page 41

宣言の構文内にも型を書けるようになった

Page 42

function add(int $a, int $b): int|float{return $a + $b;}

Page 43

関数に入出力の型を書いておくことで影響を想像しやすく

Page 44

ここまでは人間が型を付ける(書く)話

Page 45

/*** @param int $a* @param int $b* @return int|float*/function add($a, $b) {return $a + $b;}

Page 46

DocCommentとかいう机上の空論

/*** @param int $a* @param int $b* @return int|float*/function add($a, $b) {return $a + $b;}

Page 47

DocCommentとかいう机上の空論

コーディング時のヒントとして役に立つ…かもしれない

/*** @param int $a* @param int $b* @return int|float*/function add($a, $b) {return $a + $b;}

Page 48

function add(int $a, int $b): int|float{return $a + $b;}

Page 49

intしか渡されないことは実行時に保証される

function add(int $a, int $b): int|float{return $a + $b;}

Page 50

intしか渡されないことは実行時に保証される

function add(int $a, int $b): int|float

{

return $a + $b;

}

型宣言に反する値が返されたら実行時エラー

Page 51

実際には型宣言をもとに型を再構築する

Page 52

PHP

$a = 1;$b = 2;$c = $a + $b;

Page 53

PHP

C言語

$a = 1;$b = 2;$c = $a + $b;

int a = 1;int b = 2;int c = a + b;

Page 54

PHP

$a = 1;$b = 2;$c = $a + $b;

Page 55

PHP

int

$a = 1;

$b = 2;

$c = $a + $b;

Page 56

PHP

int

int

$a = 1;

$b = 2;

$c = $a + $b;

Page 57

PHP

int

int

int

$a = 1;

$b = 2;

$c = $a + $b;

Page 58

PHPでは処理系の外で静的型チェッカーの文明が広がった

Page 59

型チェッカー

$a = 1;$b = 2;$c = $a + $b;

Page 60

型チェッカー

int(1)

$a = 1;

$b = 2;

$c = $a + $b;

Page 61

型チェッカー

int(1)

int(2)

$a = 1;

$b = 2;

$c = $a + $b;

Page 62

型チェッカー

int(1)

int(2)

int(3)

$a = 1;

$b = 2;

$c = $a + $b;

Page 63

型チェッカー

$a = ‘foo’;$b = rand() === 1 ? ‘foo’ : ‘bar’;$c = $a + $b;

Page 64

'foo'型チェッカー

$a = ‘foo’;

$b = rand() === 1 ? ‘foo’ : ‘bar’;

$c = $a + $b;

Page 65

型チェッカー

'foo''foo'

$a = ‘foo’;

$b = rand() === 1 ? ‘foo’ : ‘bar’;

$c = $a + $b;

Page 66

型チェッカー

'foo''foo''bar'

$a = ‘foo’;

$b = rand() === 1 ? ‘foo’ : ‘bar’;

$c = $a + $b;

Page 67

型チェッカー

'foo''foo''bar'

$a = ‘foo’;

$b = rand() === 1 ? ‘foo’ : ‘bar’;

$c = $a + $b;

Page 68

型チェッカー

'foo''foo''bar'

$a = ‘foo’;

$b = rand() === 1 ? ‘foo’ : ‘bar’;

$c = $a + $b;

'foo'|'bar'

Page 69

型チェッカー

'foo''foo'

'bar'

$a = ‘foo’;

$b = rand() === 1 ? ‘foo’ : ‘bar’;

$c = $a + $b;

'foo'|'bar'

'foofoo'|'foobar'

Page 70

いろんなところから湧き出す

型の特定できないデータ

Page 71

arrayは無限の可能性を秘める

(悪い意味で)

Page 72

扱う対象が複数になったのに

型に反映されない

Page 73

PHPの組み込みの型機能ではどんなに型推論しても静的に型が定まらない

Page 74

無限の可能性を秘めたarrayを放置するとコード全体のエントロピーが増大しプロジェクトは熱的死を迎える

Page 75

TypeScriptにとっての型

  • 型宣言をもとに型チェックを行なって、分析情報を報告
  • 実行時には型情報は何も残らない
  • JavaScriptにコンパイル ≒ 型定義の部分をひっぺがして実行
  • Node.js 25.2ではType Strippingで直接実行できるようになった
  • 実際にはTypeScript enum など別のコード生成をする機能もある
  • 型がついたコードは実行時にはエラーが出ないでほしい(願望)

Page 76

PHPにとっての型

  • 構文内の型宣言に含まれる型情報は実行時に必ず検証される
  • エラーなく動いているとき、型宣言と実行時の状態が必ず一致する
  • 実行時に検査するのは重そうだが(先入観) 実際にはJITで最適化
  • PHPDoc(コメント)に書いた型注釈はIDE/静的解析ツールが解釈する
  • PHPDocに書かれたものは机上の空論に過ぎない

Page 77

動的言語と型

  • 自分のプロジェクト内で型を書き始めるのは簡単だが…

現実には外部のライブラリで型が書かれていないこともある

  • 型が書かれていても実態と一致しないこともよくある
  • Ruby, Python, JavaScriptでは外部プロジェクトで

ライブラリの型をメンテナンスされているものもある

  • PHPでは実行時に強制力のある型宣言があるので、

実装と一致した型がきちんと書かれていることが多い

Page 78

そんなに動的言語を書きたいか

Page 79

書きたい!

Page 80

静的型付きと動的の良いとこどりができるゆるふわ言語PHPにこれからもご期待ください