php有8种运行时真实变量类型,对应zval的type字段:boolean、integer、float、string、array、object、null、resource;mixed和callable仅为伪类型,不参与实际类型判定。

PHP变量类型不是“可选配置”,而是运行时实际存在的8种底层类型,直接决定zval结构中type字段的值。你写的每行赋值语句,都在悄悄触发类型判定和内存布局切换。
标量类型:boolean、integer、float、string 最常被误判
这四种看似简单,但容易在隐式转换中出问题:
-
is_int("123")返回false— 字符串不会自动变成整型来通过类型检查 -
1 == "1"为true,但1 === "1"是false— 松散比较会触发类型转换,严格比较才看type字段 -
0.0、-0.0、INF、NAN都属于float类型,但is_float(NAN)在某些 PHP 版本返回false(需用is_nan()单独判断) - 字符串用双引号时支持变量解析,但
'$name'和"$name"的type虽同为string,内部存储方式不同(是否启用 interned string 优化)
复合类型:array 和 object 行为差异极大
它们都占用更多内存,但生命周期和复制逻辑完全不同:
-
array是“值语义”:赋值时默认深拷贝(PHP 7+ 使用写时复制优化,表面是复制,实际共享底层HashTable,直到某一方修改) -
object是“引用语义”:赋值不复制对象本身,只复制对对象的引用(即zval中的obj指针),clone才真正复制实例 -
is_array([])和is_object(new stdClass())返回true,但gettype([])返回"array",gettype(new stdClass())返回"object"—— 这是运行时真实类型,不是类名 - 空数组
[]和空对象new stdClass()的type字段分别是IS_ARRAY和IS_OBJECT,不可互换
特殊类型:NULL 和 resource 容易被当成“无类型”
它们有明确的 type 值,但语义特殊:
-
NULL对应IS_NULL,且只有一个合法值:null(不区分大小写,但推荐小写)。未初始化变量、unset()后变量、显式赋null,三者都进入该状态 -
resource对应IS_RESOURCE,本质是 C 层句柄编号(如文件描述符、MySQL 连接 ID),get_resource_type($fp)可查具体资源类别("stream"、"mysql link"等) -
is_null($var)比$var === null更安全 —— 前者能正确处理未定义变量(不报E_NOTICE),后者会触发警告 -
resource不能序列化,不能 JSON 编码,var_dump()只显示Resource id #n,调试时需配合get_resource_type()
伪类型 mixed / callable 不是真实类型,别当真
它们只出现在文档、PHPDoc 或类型声明中,gettype() 永远不会返回 "mixed" 或 "callable":
-
callable是类型声明关键词,实际值可能是string(函数名)、array([$obj, 'method'])、Closure(匿名函数)—— 三者gettype()分别返回"string"、"array"、"object" -
mixed纯属占位符,表示“可能是任意一种真实类型”,PHP 运行时不识别它。函数签名写function foo(mixed $x),只是告诉 IDE 和静态分析工具“这里不校验类型” - PHP 8+ 支持联合类型(如
string|int),但底层仍是单个type字段;联合类型靠引擎在运行时逐个匹配,不是新类型
最常被忽略的是:类型判定发生在运行时,且每个变量独立携带类型信息。不要依赖“看起来像数字的字符串就是 int”,也不要假设“空数组和 null 行为一致”。is_*() 函数比 gettype() 更适合业务逻辑判断,因为前者考虑了语义(比如 is_numeric("0xFF") 返回 true,而 gettype("0xFF") 仍是 "string")。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











