タイトル: 型変換
SEOタイトル: PHP 型変換 (Type Juggling) 完全ガイド
| この記事の要点 |
|
明示キャスト(推奨)
$str = '42';
$num = (int)$str; // 42 (int)
$flt = (float)$str; // 42.0
$num = 42;
$str = (string)$num; // "42"
$x = 1;
$b = (bool)$x; // true
$obj = ['a' => 1, 'b' => 2];
$o = (object)$obj; // stdClass { a: 1, b: 2 }
echo $o->a; // 1
$o = new stdClass();
$o->a = 1;
$arr = (array)$o; // ['a' => 1]
// null へのキャスト (PHP 7.2 で deprecated, PHP 8.0 で削除)
$x = (null)$y; // ❌ 使わない
関数による型変換
intval('42'); // 42
intval('42abc'); // 42 (前から取れるだけ)
intval('abc'); // 0
intval('0x1A', 0); // 26 (基数 0 = 自動検出)
intval('010', 0); // 8 (8進数)
intval('1010', 2); // 10 (2進数)
floatval('3.14'); // 3.14
floatval('1e3'); // 1000.0
strval(42); // "42"
strval(3.14); // "3.14"
strval(true); // "1"
strval(false); // ""
strval(null); // ""
boolval(0); // false
boolval('false'); // true ★ 文字列 "false" は true!
settype($var, 'integer'); // $var を int に変換 (参照渡し)
gettype($var); // 型名を文字列で返す
get_debug_type($var); // gettype の改善版 (PHP 8.0+)
暗黙的型変換 (Type Juggling)
// 数値演算で文字列が数値化
"5" + 3; // 8 (int)
"5.5" + 3; // 8.5 (float)
"5abc" + 3; // 8 + Warning (PHP 8.0+)
// PHP 7.x: 8 + Notice
"abc" + 3; // 3 + TypeError (PHP 8.0+)
// 文字列連結で数値が文字列化
"foo" . 42; // "foo42"
42 . "foo"; // "42foo"
// 比較
0 == "abc"; // false (PHP 8.0+) / true (PHP 7.x) ★ 大きな変更
0 == "0"; // true
"1" == "01"; // true (両方数値文字列なので数値比較)
"10" == "1e1"; // true (科学記法)
100 == "1e2"; // true
[] == false; // true
null == false; // true
null == 0; // true
"" == 0; // false (PHP 8.0+) / true (PHP 7.x)
PHP 8.0 の比較ルール変更
「数値 vs 数値以外の文字列」の == 比較は、PHP 7 まで「文字列を数値に変換」していましたが、PHP 8 では「数値を文字列に変換」に変わりました。
| 比較 | PHP 7.x | PHP 8.0+ |
|---|---|---|
0 == "abc" | true(文字列 → 0) | false(0 → "0") |
0 == "" | true | false |
0 == "0" | true | true(変わらず) |
"1" == "01" | true | true(変わらず) |
falsy 値の一覧
if ($x) や !$x で false 扱いになる値:
false0(int)0.0(float)-0.0""(空文字)"0"★ 注意("false" や "0.0" は truthy)null[](空配列)SimpleXMLElementの空オブジェクト
if (0) { /* skip */ }
if ("0") { /* skip */ } // ★ "0" は falsy
if ("0.0") { /* run */ } // "0.0" は truthy
if ("false") { /* run */ } // 文字列 "false" は truthy
if (null) { /* skip */ }
if ([]) { /* skip */ }
if (new stdClass) { /* run */ } // 空オブジェクトは truthy
// 厳密判定
$x === null; // null のみ
$x === false; // false のみ
$x === 0; // 0 のみ
$x === ''; // 空文字のみ
strict_types で厳密化
ファイル先頭に declare(strict_types=1); を書くと、関数引数・戻り値の型チェックが厳しくなり、暗黙変換が TypeError になります:
JavaScript の == vs === との対比
| 式 | PHP == | PHP === | JS == | JS === |
|---|---|---|---|---|
1 == "1" | true | false | true | false |
0 == false | true | false | true | false |
null == undefined | N/A | N/A | true | false |
NaN == NaN | true (PHP) | true | false | false |
結論: PHP も JS も、基本 === を使うのが安全。
var_dump でデバッグ
var_dump("42"); // string(2) "42"
var_dump(42); // int(42)
var_dump(42.0); // float(42)
var_dump(true); // bool(true)
var_dump(null); // NULL
var_dump([1, 2]); // array(2) { [0]=> int(1) [1]=> int(2) }
var_dump((array)"hello"); // array(1) { [0]=> string(5) "hello" }
// get_debug_type (PHP 8.0+)
echo get_debug_type(42); // int
echo get_debug_type(new stdClass); // stdClass
echo get_debug_type(fopen('php://memory', 'r')); // resource (stream)
FAQ
Q: (int)"3.99" はいくつ?
A: 3。小数部は切り捨て(負数も 0 方向)。四捨五入したいなら round()。
Q: 配列 → 文字列のキャストは?
A: (string)[1,2,3] は "Array" + Warning。実用上は implode(',', $arr) や json_encode。
Q: オブジェクト → 配列は private プロパティも入る?
A: 入りますが、キーが "\0ClassName\0prop" のようになります。get_object_vars の方が扱いやすい。