PHPで日常的に使う型は8つあります。int、float、string、bool、array、object、null、そして受け渡しする関数のためのcallableです。変数そのものに固定の型はなく、今入っている値が型を持っています。var_dump($x)は型と値の両方を表示し、gettype($x)は型を文字列で返します。
1列目がgettype()、2列目がget_debug_type()です。値を自分のものに置き換えて、もう一度実行してみてください。いくつかの名前は一致しません。gettypeは歴史的な理由でinteger、double、booleanと答えますが、get_debug_typeは型宣言と同じ名前(int、float、bool)を使い、オブジェクトならクラス名を返します。
PHPの型の一覧
| 型 | 例 | 補足 |
|---|---|---|
int | 42, -7, 0x1A, 1_000_000 | 整数。今の環境では64ビット |
float | 3.14, 1.5e3 | 小数。どの言語とも同じく誤差がある |
string | "hi", 'hi' | 文字ではなくバイトの並び |
bool | true, false | 大文字小文字を区別しない(TRUEも可) |
array | [1, 2], ["a" => 1] | 順序付きマップ。リストと辞書を兼ねる |
object | new User(), new stdClass() | クラスのインスタンス |
null | null | null型の唯一の値。「値が設定されていない」の意味も |
callable | 'strlen', fn($x) => $x * 2 | 呼び出せるものすべて |
iterable | 配列またはTraversableオブジェクト | foreachが受け付けるもの |
resource | fopen()の結果 | PHPの外にあるものへのハンドル |
var_dumpで値を調べる
var_dumpは、実際に何が入っているかを確かめるための道具です。型と値を表示し、文字列ならバイト単位の長さも表示します。
echoだと最初の3つはどれも10と表示され、違いがわかりません。string(5) "café"の長さはバイト数なので、ASCII以外のテキストではstrlenとmb_strlenの結果が違います。
整数と浮動小数点数
整数は小数部分のない数です。リテラルには読みやすさのためにアンダースコアを入れられ、16進数、8進数、2進数の表記も使えます。floatは小数点か指数を持つ数で、どの言語とも同じく、ほとんどの小数は近似値で保存されます。
floatを==で比較してはいけません。差を小さな許容値と比べるか、先に両辺を丸めます。金額はセント単位の整数で保存しましょう。
真偽値とfalseになる値
boolはtrueかfalseです。PHPが条件を期待する場所(if、while、!)では、どんな値もboolに変換され、ごく一部の値がfalseとして扱われます:false、0、0.0、""、"0"、[]、null。それ以外はすべてtrueです。次の表は、各値の型、boolへの変換結果、数値かどうかを示しています。
| $x | gettype | bool | is_numeric |
|---|---|---|---|
| 0 | |||
| 1 | |||
| -1 | |||
| 0.0 | |||
| 1.5 | |||
| "0" | |||
| "" | |||
| " " | |||
| "0.0" | |||
| "10" | |||
| "1e1" | |||
| "abc" | |||
| "null" | |||
| true | |||
| false | |||
| null | |||
| [] | |||
| [0] |
意外なのは"0.0"、" "、"null"です。3つとも"0"以外の空でない文字列なのでtrueになり、if ($value)の中身が実行されます。
配列、オブジェクト、null
配列は、整数か文字列のキーの下にどんな値でも混ぜて持てます。オブジェクトはクラスのインスタンスです。stdClassは手早くオブジェクトを作るためのPHPの空のクラスで、(object)で配列をオブジェクトに変えられます。nullは「値がない」ことを表します。
is_*関数で型を確認する
型ごとに、trueかfalseを返す判定関数があります。is_numericはis_intとは違い、数値の文字列も受け付けます。フォームの入力を確認するときに欲しいのはこちらです。
ほかにis_bool、is_array、is_object、is_null、is_callable、is_iterableがあり、特定のクラスかどうかは$x instanceof ClassNameで調べます。
型の自動変換とstrict_types
演算子が別の型を必要とするとき、PHPは自動で型を変換します。計算に使った数値の文字列は数値になり、.は数値を文字列にします。まったく数値でない文字列は足し算できず、PHP 8はTypeErrorを投げます。
型付きの引数も変換されますが、ファイルがdeclare(strict_types=1);で始まっている場合は別です。その場合、間違ったスカラー型での呼び出しは変換されずに失敗します。
意図して変換するにはキャストします:(int) "42"、(float) "3.5"、(string) 10、(bool) "0"。すべてのキャストと注意点は型キャストのページにあります。
よくあるミス:異なる型を==で比較する
==は比較の前に変換するので、型の違う2つの値がバグの原因になる形で「等しい」ことがあります。たとえば"1e1" == "10"(どちらも数値の10)やnull == falseです。変換させたいのでなければ、型も一致することを求める===を使いましょう。
PHP 8で最悪のケースは直りました。"abc" == 0は以前はtrueでしたが、数値でない文字列は文字列として比較されるようになったので、今はfalseです。完全な表は比較演算子のページにあります。
よくある質問
PHPで変数の型を確認するには?
var_dump($x)は型と値を表示します(例:int(5))。gettype($x)は型名を文字列("integer")で返し、get_debug_type($x)は今の名前("int"、オブジェクトならクラス名)を返します。特定の型かどうかを調べるには、is_int、is_string、is_arrayなどのis_*関数を使います。
gettypeがfloatに対して"double"を返すのはなぜですか?
歴史的な理由で、gettype()はfloatを"double"、整数を"integer"と報告します。PHP 8で追加されたget_debug_type()は、型宣言で書くのと同じ名前の"float"と"int"を返します。
PHPでfalseになる値はどれですか?
boolに変換すると、false、0、0.0、""、"0"、[]、nullがfalseになります。それ以外はすべてtrueで、"0.0"、" "、"false"もtrueです。
PHPの整数の最大値はいくつですか?
PHP_INT_MAXで、64ビット環境では9223372036854775807です。これを超えて足しても値は一周せず、結果はfloatになって精度が落ちます。
PHPは強い型付けと弱い型付けのどちらですか?
PHPは動的型付けで、デフォルトでは可能なら型を変換します("10" + 5は15)。ファイルの先頭にdeclare(strict_types=1);を書くと、そのファイル内での型付き関数の呼び出しは、間違ったスカラー型を変換せずにTypeErrorで拒否します。