is_resource()仅检测变量是否为资源类型,不验证其有效性;MySQLi连接需用ping()或异常捕获判断可用性,文件操作应结合is_readable()/flock(),PHP 8+中许多资源已转为对象,需改用is_object()等替代方案。
只能告诉你变量“是不是资源类型”,
不能保证它当前有效可用
。很多开发者误以为
返回
就能放心读写,结果在
或
时突然失败——因为资源可能已被关闭、超时断开,或底层句柄已失效。
is_resource() 的真实行为:只认类型,不验状态
是个轻量级类型检查函数,它不做任何 I/O 或系统调用,只查 PHP 内部的资源标头。这意味着:
若
成功,
返回
若随后执行了
,再调用
就返回
(资源标头被清空)
但若资源是远程数据库连接,
成功后网络中途断开,
仍返回
——它根本不知道连接已死
所以它适合做「类型兜底」,比如防止把字符串当文件句柄传给
,但绝不能替代「可用性验证」。
判断 MySQLi 连接是否真可用:别只靠 is_resource()
对
实例,
在 PHP 8+ 已不适用(
对象不是 resource),而老版本即使返回
,也不代表连接还活着。
立即学习
“
PHP免费学习笔记(深入)
”;
正确做法是调用
:它发一个轻量心跳包,成功则重置连接状态,失败则触发 reconnect(若启用)或返回
更稳妥的是捕获查询异常:
注意:
属性只反映初始化错误,不反映运行中断连
示例:
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
文件句柄有效性:is_resource() + is_readable()/is_writable()
文件资源比网络连接“实在”,但仍有陷阱:
为
,只说明
是个打开的句柄,不代表文件没被其他进程删除或权限被回收
读操作前加
(注意:传路径,不是句柄)更可靠,但它依赖
,有性能开销
写操作前建议先
尝试非阻塞加锁,失败说明文件正被占用或不可写
用完必须显式
,并设
,否则残留变量可能误导后续
判断
PHP 8+ 中资源类型的迁移坑:is_resource() 失效场景
PHP 版本升级后,不少扩展把 resource 改成了 object,继续用
会永远返回
:
在 PHP 8.0+ 返回
对象,不再是 resource → 改用
的
从 resource 变成
→ 检查应改为
、
等也陆续转向对象模型,
不再是通用方案
迁移时务必查对应扩展的变更日志,别依赖旧文档里的 resource 描述。
实际项目里,资源有效性从来不是单点判断的事——它取决于类型、上下文、PHP 版本和运行时状态。最危险的,就是把
当成“健康检查”用。
is_resource()is_resource($handle)truefread()mysqli_query()is_resource()$fp = fopen('/tmp/test.txt', 'r')is_resource($fp)truefclose($fp)is_resource($fp)falsemysqli_connect()is_resource($conn)truefgets()mysqliis_resource()mysqlitrue$mysqli->ping()falsetry { $mysqli->query('SELECT 1'); } catch (mysqli_sql_exception $e) { /* 连接已断 */ }mysqli::connect_errorif ($mysqli instanceof mysqli && $mysqli->ping()) {
// 可安全执行查询
} else {
error_log('MySQL connection lost');
// 重建连接或抛出异常
}is_resource($fp)true$fpis_readable($filename)stat()flock($fp, LOCK_EX | LOCK_NB)fclose($fp)$fp = nullis_resource()is_resource()falsehash_init()HashContextis_object($ctx) && method_exists($ctx, 'update')SoapClient$client->typemaparrayisset($client->typemap) && is_array($client->typemap)XMLWriterZipArchiveis_resource()is_resource()