declare(strict_types=1) で型の異なる引数を渡すと TypeError になる
ファイルの先頭でdeclare(strict_types=1)を宣言すると、関数の型宣言と異なる型の値を渡した際に自動変換されず、TypeErrorになります。strict_typesが無い場合は自動的に型変換されて実行が続きます。
エラーメッセージの読み方
Fatal error: Uncaught TypeError: add(): Argument #2 ($b) must be of type int, string given, called in main.php on line 6 and defined in main.php:3
main.php- ファイル名
3- 行番号 — 実際にクラッシュした行
TypeError- 例外クラス — 何が起きたか。ここを検索するのが最短です
add(): Argument #2 ($b) must be of type int, string given, called in main.php on line 6 and defined- 内容 — どの値が問題だったか
このエラーが出る典型パターン
パターン1
1 <?php 2 declare(strict_types=1); 3 function add(int $a, int $b): int { 4 return $a + $b; 5 } 6 echo add(1, "2" ); ^
Fatal error: Uncaught TypeError: add(): Argument #2 ($b) must be of type int, string given, called in main.php on line 6 and defined in main.php:3
strict_types=1を宣言したファイルでは、int型の引数に文字列を渡しても自動変換されずTypeErrorになります。数値そのものを渡す必要があります。
直し方: "2" を 2 にします。
広告
広告スロット(未設定)
パターン2
1 <?php 2 declare(strict_types=1); 3 function double(float $n): float { 4 return $n * 2; 5 } 6 echo double("3.5" ); ^
Fatal error: Uncaught TypeError: double(): Argument #1 ($n) must be of type float, string given, called in main.php on line 6 and defined in main.php:3
strict_typesが有効な状態でfloat型の引数に文字列を渡すとTypeErrorです。数値リテラルとして渡す必要があります。
直し方: "3.5" を 3.5 にします。
パターン3
1 <?php 2 declare(strict_types=1); 3 function repeat(string $s, int $times): string { 4 return str_repeat($s, $times); 5 } 6 echo repeat("ab", "3" ); ^
Fatal error: Uncaught TypeError: repeat(): Argument #2 ($times) must be of type int, string given, called in main.php on line 6 and defined in main.php:3
int型の引数に文字列"3"を渡すと、strict_types下では自動変換されずTypeErrorになります。
直し方: "3" を 3 にします。
よくある誤解
「PHPは型に緩い言語だから、int型の引数に文字列を渡しても自動変換されるはず」という思い込みは、strict_typesを宣言したファイルには当てはまりません。宣言した瞬間からそのファイル内の型チェックは厳格になります。
まとめ
declare(strict_types=1) で型の異なる引数を渡すと TypeError になるは中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。