类型检测 #

一、类型检测函数 #

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