is_resource仅用于资源类型快筛,不可验证可用性; fopen失败返回false、资源已释放或变量非resource时均返回false;PHP 8+中hash_init等返回对象,应改用is_object()。

is_resource 什么时候该用、什么时候不该用
它只适合做「类型快筛」,不是资源「可用性验证」。比如你刚调用 fopen(),想确认返回值没出错(比如文件不存在导致返回 false),这时用 is_resource() 是合理的;但如果你已经拿到一个数据库连接变量,想判断它是否还能执行查询,is_resource() 就完全没用——连接可能已断开,但变量仍是 resource 类型。
常见误用场景:
- 用
is_resource($mysqli)替代$mysqli->ping() - 在
fclose()后还拿原变量反复调is_resource()判断“是不是还能用” - 对
SoapClient::$typemap或 ext/hash 的哈希上下文句柄(PHP 8.0+)调用is_resource()——这些在新版中已不是 resource
is_resource 返回 false 的 3 种典型原因
is_resource() 返回 false 不代表“出错了”,只说明变量当前不指向有效 resource。具体分三类:
-
false、null、未定义变量:比如fopen("missing.txt", "r")失败时返回false,is_resource(false)必然为false - 资源已被释放:调用
fclose($fp)或curl_close($ch)后,变量仍存在,但底层句柄已销毁,is_resource($fp)立即返回false - 变量根本不是 resource:比如字符串
"hello"、数组[]、对象new DateTime(),或 PHP 8+ 中的hash_init("sha256")返回的对象
替代方案:PHP 8+ 中哪些 resource 检查要改写
PHP 版本升级后,不少扩展把 resource 改成了 object,继续用 is_resource() 会漏判或逻辑翻车:
立即学习“PHP免费学习笔记(深入)”;
- ext/hash:PHP 8.0 起
hash_init()返回HashContext对象,应改用is_object($ctx) && method_exists($ctx, "update")或直接 try/catch - SoapClient:
$client->typemap在 PHP 8.1+ 是array,检查前先判!is_null($client->typemap),别再is_resource($client->typemap) - PDOStatement:不是 resource,是 object,用
is_object($stmt) && $stmt instanceof PDOStatement
顺带一提:get_resource_type() 在非 resource 上会报 warning,比 is_resource() 更激进,别在不确定类型时直接用。
实际代码里怎么安全地配合资源生命周期
资源管理的核心不是“检测”,而是“确定释放时机”。is_resource() 最实用的位置,是在释放前兜底判断:
- 函数退出前统一清理:先
if (is_resource($fp)) { fclose($fp); },避免对 null 或 false 调fclose()报 warning - 异常流程中:try 里打开资源,finally 里用
is_resource()判定再关闭,防止因异常跳过释放 - CLI 长任务中:每轮循环结束后显式
fclose($fp); $fp = null;,而不是依赖脚本结束自动回收
真正容易被忽略的是:resource 变量被 unset() 或重赋值后,如果底层句柄没被显式关闭,PHP 内核仍会持有它直到脚本结束——这种泄漏在高并发 CLI 场景下会快速耗尽系统文件描述符。



















