タイトル: データ型
SEOタイトル: PHP データ型完全ガイド (Type Declarations/Union/Nullable/Enum)
| この記事の要点 |
|
PHP のデータ型 一覧
| 分類 | 型 | 例 |
|---|---|---|
| プリミティブ | bool | true / false |
int | 10 / 0xFF / 0b1010 | |
float (double) | 3.14 / 1.5e3 | |
string | 'hello' / "world" | |
| 複合 | array | [1,2,3] / ['k'=>'v'] |
object | new User() | |
callable | 'strlen' / fn() => 1 | |
iterable | array / Traversable | |
| 特殊 | null | null |
resource | fopen の戻り等 (PHP 8 で多くが Object 化) |
型の検査関数
var_dump(is_int(10)); // true
var_dump(is_string('hi')); // true
var_dump(is_array([1,2])); // true
var_dump(is_bool(false)); // true
var_dump(is_float(3.14)); // true
var_dump(is_null(null)); // true
var_dump(is_object(new stdClass())); // true
var_dump(is_callable('strlen')); // true
// PHP 8+ get_debug_type (より正確)
echo get_debug_type(10); // int
echo get_debug_type(3.14); // float
echo get_debug_type(new User()); // App\User
// 旧 gettype (歴史的事情で integer/double を返す)
echo gettype(10); // integer
echo gettype(3.14); // double
Type Declarations (PHP 7+)
// 引数 + 戻り値の型宣言
function greet(string $name, int $age): string {
return "Hi $name ($age)";
}
// クラスもプロパティに型 (PHP 7.4+)
class User {
public int $id;
public string $name;
public ?string $email; // Nullable
public array $roles = [];
}
// インタフェース / 抽象型
function process(iterable $items): void {
foreach ($items as $item) { /* ... */ }
}
// self / static / parent
class Builder {
public function with(string $k, $v): static {
// ...
return $this;
}
}
Nullable / Union / Mixed / Intersection
// Nullable (PHP 7.1+)
function find(int $id): ?User {
return User::find($id); // User か null
}
// Union Types (PHP 8.0+)
function format(int|float $n): string {
return number_format($n, 2);
}
// Mixed (PHP 8.0+)
function debug(mixed $value): void {
var_dump($value);
}
// Intersection Types (PHP 8.1+)
function process(Countable&Iterator $obj): void {
echo count($obj);
foreach ($obj as $v) { /* ... */ }
}
// Disjunctive Normal Form Types (PHP 8.2+)
function f((A&B)|null $x): void {}
// never (PHP 8.1+) - 戻らない
function fail(string $msg): never {
throw new Exception($msg);
}
Enum (PHP 8.1+)
// 基本 Enum
enum Status {
case Pending;
case Active;
case Banned;
}
// Backed Enum (値を持つ)
enum HttpMethod: string {
case Get = 'GET';
case Post = 'POST';
case Put = 'PUT';
public function isSafe(): bool {
return $this === self::Get;
}
}
// 利用
$status = Status::Active;
match ($status) {
Status::Active => 'OK',
Status::Pending => 'Wait',
Status::Banned => 'NG',
};
// 文字列から復元
$m = HttpMethod::from('GET');
$m = HttpMethod::tryFrom('UNKNOWN'); // null
Type Juggling と strict_types
PHP は 暗黙的に型変換します。これは便利な反面、バグの温床にもなります:
// 暗黙変換
var_dump('1' == 1); // true (緩い比較で数値化)
var_dump('1' === 1); // false (厳密比較)
var_dump('1abc' + 1); // PHP 7: 2 警告, PHP 8: TypeError
// 関数引数の型変換
function add(int $a, int $b): int { return $a + $b; }
echo add('5', '10'); // 15 (文字列 → int 自動変換)
// strict_types で厳格化
declare(strict_types=1);
function addStrict(int $a, int $b): int { return $a + $b; }
echo addStrict('5', '10'); // TypeError !
// 比較演算子
var_dump(0 == 'abc'); // PHP 7: true, PHP 8: false
var_dump(null == false); // true
var_dump(null === false); // false
キャスト演算子
$n = (int) '123abc'; // 123 (前から読める分)
$f = (float) '3.14'; // 3.14
$s = (string) 100; // '100'
$b = (bool) ''; // false ('', '0', 0, 0.0, null, [] は false)
$a = (array) 'x'; // ['x']
$o = (object) ['n' => 1]; // stdClass {n: 1}
// 関数による変換
$i = intval('123');
$f = floatval('3.14');
$s = strval(100);
$b = boolval('0'); // false
// settype (in-place)
$x = '100';
settype($x, 'integer'); // $x は int 100
FAQ
Q: declare(strict_types=1) は付けるべき?
A: 新規プロジェクトなら強く推奨。型安全性が向上し、暗黙変換による予期せぬバグを防げます。
Q: float の比較で 0.1 + 0.2 === 0.3 が false に
A: IEEE 754 浮動小数の精度問題。abs($a - $b) < PHP_FLOAT_EPSILON で比較するか、BCMath 拡張を使ってください。
Q: int の最大値は?
A: 64bit PHP では PHP_INT_MAX = 9223372036854775807。超えると float に変換されます。