38
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PHP の型宣言は変数の型のチェックではない

Posted at

タイトルのとおりです。

<?php
function add(int $a, int $b): int
{
    return $a + $b;
}

echo add(1, 2.2) . "\n";   // 3
echo add(1, "2") . "\n";   // 3
echo add(1, "1e1") . "\n";   // 11

add(1, "two"); // Fatal error: Uncaught TypeError: add(): Argument #2 ($b) must be of type int, string given

<?php
function not(bool $b): bool
{
    return !$b;
}

var_dump(not(0));    // true
var_dump(not(""));   // true

not(null); // Fatal error: Uncaught TypeError: not(): Argument #1 ($b) must be of type bool, null given

値の型そのものを見ているわけではなく、値の内容が目的の型に変換できるかどうかが判断基準になっていて、受け入れられると型変換されます。

Web の入力バリデーションで「数字だけで構成されるから数値としてOK」と判断された文字列は、値の型が int にならず文字列のままでも心配ありません。実質 int の string は int 引数の関数に渡せます。DB で integer 型とわかっているものなら、PHP に渡ってくるとき値の型が文字列でも int 引数の関数に安心して渡せます。

PHP は強い型の値を持ちながら、意図的に弱い型のような振る舞いさせる言語です。文字列 IO と親密な関係にあるため、そういう設計方針が適しています。

<?php
function number(...$args): int
{
    return implode('', $args);
}

var_dump(number('1', '2', '3'));  // int(123)

number('4', 'five');
// PHP8: Fatal error
// PHP7: Notice

戻り値の型チェックもなかなかダイナミックです。型そのものではなく、値の内容がじっさいに変換できるかどうかが問われることがよくわかる例ですね。

変数だけを見て型がわからないので、コンパイル時型推論でガチガチにする言語と PHP の型とはコンセプトがまったく異なる概念だと意識すると、もっと PHP と仲良くできそうです。

38
16
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
38
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?