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|(cid:210)oat
*/
function add($a, $b) {
return $a + $b;

}

Page 41

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

Page 42

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

Page 43

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

Page 44

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

Page 45

/**
* @param int $a * @param int $b
* @return int|(cid:210)oat
*/
function add($a, $b) {
return $a + $b;
}

Page 46

DocCommentとかいう

/**

机上の空論

* @param int $a * @param int $b
* @return int|(cid:210)oat
*/
function add($a, $b) {
return $a + $b;
}

Page 47

DocCommentとかいう

/**

机上の空論

* @param int $a * @param int $b
* @return int|(cid:210)oat
*/
function add($a, $b) {

コーディング時の
ヒントとして役に立つ…

return $a + $b;

かもしれない

}

Page 48

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

Page 49

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

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

Page 50

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

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

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

Page 51

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

Page 52

PHP

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

Page 53

C言語

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

Page 58

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

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)

$a = 1; $b = 2;

int(3)

$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に
これからもご期待ください