类型检测 #
一、类型检测函数 #
1.1 gettype() #
获取变量的类型:
php
<?php
echo gettype(42);
echo gettype(3.14);
echo gettype("hello");
echo gettype(true);
echo gettype([1, 2, 3]);
echo gettype(new stdClass());
echo gettype(null);
echo gettype(fopen('php://stdin', 'r'));
返回值:
- “integer”
- “double”
- “string”
- “boolean”
- “array”
- “object”
- “NULL”
- “resource”
- “unknown type”
1.2 get_debug_type() #
PHP 8.0+ 提供更友好的类型名称:
php
<?php
echo get_debug_type(42);
echo get_debug_type(3.14);
echo get_debug_type("hello");
echo get_debug_type(true);
echo get_debug_type([1, 2, 3]);
echo get_debug_type(new stdClass());
echo get_debug_type(null);
| 值 | gettype() | get_debug_type() |
|---|---|---|
| 42 | “integer” | “int” |
| 3.14 | “double” | “float” |
| true | “boolean” | “bool” |
| null | “NULL” | “null” |
| [] | “array” | “array” |
二、is_* 类型检测函数 #
2.1 标量类型检测 #
php
<?php
var_dump(is_int(42));
var_dump(is_int(3.14));
var_dump(is_integer(42));
var_dump(is_float(3.14));
var_dump(is_float(42));
var_dump(is_double(3.14));
var_dump(is_string("hello"));
var_dump(is_string(42));
var_dump(is_bool(true));
var_dump(is_bool(1));
2.2 复合类型检测 #
php
<?php
var_dump(is_array([1, 2, 3]));
var_dump(is_array("array"));
var_dump(is_object(new stdClass()));
var_dump(is_object([]));
var_dump(is_callable('strlen'));
var_dump(is_callable(['DateTime', 'createFromFormat']));
var_dump(is_callable(function() {}));
var_dump(is_iterable([1, 2, 3]));
var_dump(is_iterable(new ArrayIterator([1, 2])));
2.3 特殊类型检测 #
php
<?php
var_dump(is_null(null));
var_dump(is_null(0));
var_dump(is_null(""));
$fp = fopen('php://stdin', 'r');
var_dump(is_resource($fp));
fclose($fp);
var_dump(is_resource($fp));
2.4 数值检测 #
php
<?php
var_dump(is_numeric(42));
var_dump(is_numeric(3.14));
var_dump(is_numeric("42"));
var_dump(is_numeric("3.14"));
var_dump(is_numeric("42abc"));
var_dump(is_numeric("0x1A"));
var_dump(is_scalar(42));
var_dump(is_scalar("hello"));
var_dump(is_scalar([1, 2, 3]));
2.5 类型检测函数列表 #
| 函数 | 说明 |
|---|---|
| is_int() / is_integer() | 是否为整数 |
| is_float() / is_double() | 是否为浮点数 |
| is_string() | 是否为字符串 |
| is_bool() | 是否为布尔值 |
| is_array() | 是否为数组 |
| is_object() | 是否为对象 |
| is_null() | 是否为null |
| is_resource() | 是否为资源 |
| is_callable() | 是否为可调用 |
| is_iterable() | 是否可迭代 |
| is_numeric() | 是否为数字或数字字符串 |
| is_scalar() | 是否为标量类型 |
| is_countable() | 是否可计数 |
三、严格类型模式 #
3.1 开启严格模式 #
在文件开头使用 declare(strict_types=1):
php
<?php
declare(strict_types=1);
function add(int $a, int $b): int
{
return $a + $b;
}
add(1, 2);
add("1", "2");
3.2 严格模式作用范围 #
严格模式只影响当前文件:
php
<?php
declare(strict_types=1);
function process(int $value): int
{
return $value;
}
include 'non_strict_file.php';
3.3 弱类型模式(默认) #
默认情况下,PHP会自动转换类型:
php
<?php
function add(int $a, int $b): int
{
return $a + $b;
}
echo add("10", "20");
echo add(10.5, 20.5);
四、类型声明 #
4.1 参数类型声明 #
php
<?php
function greet(string $name): void
{
echo "Hello, $name";
}
function calculate(int $a, float $b): float
{
return $a + $b;
}
function process(array $data): void
{
print_r($data);
}
4.2 返回值类型声明 #
php
<?php
function getName(): string
{
return "John";
}
function getAge(): int
{
return 25;
}
function getItems(): array
{
return [1, 2, 3];
}
function getUser(): ?User
{
return new User();
}
4.3 可空类型 #
php
<?php
function findUser(int $id): ?User
{
if ($id > 0) {
return new User($id);
}
return null;
}
function process(?string $value): void
{
if ($value !== null) {
echo $value;
}
}
4.4 void 返回类型 #
php
<?php
function logMessage(string $message): void
{
echo $message;
}
function setConfig(array $config): void
{
$this->config = $config;
}
4.5 never 返回类型(PHP 8.1+) #
php
<?php
function redirect(string $url): never
{
header("Location: $url");
exit;
}
function throwError(string $message): never
{
throw new Exception($message);
}
4.6 混合类型(PHP 8.0+) #
php
<?php
function process(mixed $value): mixed
{
if (is_int($value)) {
return $value * 2;
}
if (is_string($value)) {
return strtoupper($value);
}
return $value;
}
4.7 联合类型(PHP 8.0+) #
php
<?php
function format(int|float $number): string
{
return number_format($number, 2);
}
function getId(): int|string
{
return $this->id;
}
function process(array|Collection $items): int
{
return count($items);
}
4.8 交叉类型(PHP 8.1+) #
php
<?php
interface Serializable
{
public function serialize(): string;
}
interface Jsonable
{
public function toJson(): string;
}
function process(Serializable&Jsonable $object): void
{
echo $object->serialize();
echo $object->toJson();
}
五、类型检测最佳实践 #
5.1 使用类型声明 #
php
<?php
declare(strict_types=1);
class UserService
{
public function find(int $id): ?User
{
return $this->repository->find($id);
}
public function create(array $data): User
{
return $this->repository->create($data);
}
}
5.2 验证输入 #
php
<?php
function processInput(mixed $input): string
{
if (!is_string($input)) {
throw new InvalidArgumentException(
"Expected string, got " . get_debug_type($input)
);
}
return trim($input);
}
5.3 使用断言 #
php
<?php
function divide(float $a, float $b): float
{
assert($b !== 0.0, "Divisor cannot be zero");
return $a / $b;
}
5.4 类型检查工具 #
php
<?php
class TypeHelper
{
public static function ensureInt(mixed $value): int
{
if (!is_int($value)) {
throw new TypeError(
"Expected int, got " . get_debug_type($value)
);
}
return $value;
}
public static function ensureString(mixed $value): string
{
if (!is_string($value)) {
throw new TypeError(
"Expected string, got " . get_debug_type($value)
);
}
return $value;
}
}
六、instanceof 操作符 #
6.1 基本用法 #
php
<?php
class User {}
class Admin extends User {}
$user = new User();
$admin = new Admin();
var_dump($user instanceof User);
var_dump($admin instanceof User);
var_dump($user instanceof Admin);
6.2 接口检查 #
php
<?php
interface Loggable {}
class User implements Loggable {}
$user = new User();
var_dump($user instanceof Loggable);
6.3 否定形式 #
php
<?php
if (!($user instanceof Admin)) {
echo "需要管理员权限";
}
6.4 类名字符串 #
php
<?php
$className = 'User';
var_dump($user instanceof $className);
七、类型推断 #
7.1 变量类型推断 #
php
<?php
$a = 42;
$b = "hello";
$c = [1, 2, 3];
$d = new DateTime();
7.2 函数返回类型推断 #
php
<?php
function getValue()
{
return 42;
}
echo gettype(getValue());
八、总结 #
本章学习了:
- gettype() 和 get_debug_type() 函数
- is_* 系列类型检测函数
- 严格类型模式
- 各种类型声明
- instanceof 操作符
- 类型检测最佳实践
下一章将学习PHP运算符。
最后更新:2026-03-26