判断变量是否为资源类型唯一可靠方式是is_resource(),它只校验资源索引是否存在资源表中,对已关闭资源仍返回true;需结合具体函数(如mysqli_ping、feof)或异常捕获确认有效性。

用 is_resource() 判断变量是否为资源
PHP 中判断一个变量是不是资源类型,唯一可靠、语义明确的方式就是用 is_resource()。它专为此设计,返回布尔值,不依赖类型转换或字符串匹配。
常见错误是拿 gettype($var) === 'resource' 或 get_resource_type($var) 来判断——前者在 PHP 8+ 对已关闭资源会返回 'unknown',后者在变量根本不是资源时直接报 Warning: get_resource_type(): supplied argument is not a valid resource。
-
is_resource()对已关闭的资源(如fclose()后)仍返回true,这是它的行为特征,不是 bug - 若需同时确认资源“有效且未关闭”,得配合具体函数检查,比如文件资源用
feof()+fstat()或尝试读写 - 该函数性能开销极低,可放心用于高频逻辑中
资源变量被关闭后 is_resource() 仍为 true 的原因
PHP 的资源类型本质是内部指针索引,is_resource() 只校验这个索引是否还存在于资源表中,不检查底层句柄是否有效。所以 fclose($fp) 后,$fp 还是资源类型,只是内容不可用。
这导致很多实际问题:比如把已关闭的 mysqli 连接传给 mysqli_query(),会报 mysqli_query(): Couldn't fetch mysqli;或者对已释放的 cURL 句柄调 curl_exec(),返回 false 且无明确提示。
立即学习“PHP免费学习笔记(深入)”;
- 不要仅靠
is_resource()做业务逻辑分支,尤其涉及 I/O 操作前 - 对数据库连接,优先用
mysqli_ping()或pg_connection_status() - 对文件句柄,可用
stream_get_meta_data($fp)['eof']辅助判断状态,但最稳妥仍是捕获操作异常
替代方案为什么不可靠:比如 gettype() 和 instanceof
gettype() 返回字符串,看似直观,但它在资源关闭后可能返回 'unknown'(PHP 8.0+),也可能返回 'resource (closed)'(某些 SAPI 下),行为不一致;而 instanceof 完全无效——资源不是对象,没有类名,写 $var instanceof stdClass 会直接报错或恒为 false。
-
is_scalar()、is_object()、is_array()都无法覆盖资源类型判断场景 - 有人用
!is_null($var) && !is_bool($var) && ...排除法,既难维护又漏边界(比如NULL和FALSE都可能来自资源操作失败) - 硬编码类型字符串(如
strpos((string)$var, 'Resource id') !== false)在不同 PHP 版本和输出环境下极易失效
实际使用中容易忽略的典型场景
资源变量常来自函数返回,但并非所有“看起来像资源”的返回值都真是资源——比如 fopen() 失败时返回 false,mysql_connect()(已废弃)失败也返回 false,而 curl_init() 总是返回资源(即使后续 curl_setopt() 配置出错)。
- 必须在调用资源创建函数后立刻检查返回值:
$fp = fopen('file.txt', 'r'); if ($fp === false) { /* handle error */ } -
mysqli_connect()成功返回对象,失败才返回false,它不属于资源类型,不能用is_resource() - 扩展模块(如
gd、openssl)返回的资源,命名和生命周期规则各异,但is_resource()判断逻辑统一有效
资源类型本身不透明,PHP 不提供通用的“验证有效性”函数,能做的只有两步:先用 is_resource() 确认类型,再根据具体资源种类调对应的状态检查函数或捕获操作异常。










