@ 可抑制 fopen() 和 file_put_contents() 的错误输出,但需手动检查返回值并结合 error_get_last() 获取失败原因,同时应优先通过 is_writable() 和 mkdir(..., true) 预检并创建目录。

用 @ 抑制 fopen() 和 file_put_contents() 的错误输出
PHP 创建文件时如果目录不可写、路径非法或磁盘满,会直接报 Warning: fopen(): failed to open stream 这类错误。想静默创建(不显示错误但继续执行),最直接的方式是在函数前加 @ 符号——它会临时关闭该语句的错误报告。
但要注意:@ 不会阻止错误发生,只是不让错误显示到页面或日志(取决于 error_reporting 设置),也不影响函数返回值判断。
-
@fopen('log.txt', 'w')返回false时说明创建失败,必须手动检查 -
@file_put_contents('data.json', '{}')返回false或写入字节数,失败时不抛异常也不提示 - 若已开启
display_errors = On,@是唯一能阻止页面刷出警告的方式(比改配置更轻量)
用 is_writable() + mkdir() 预检路径再创建,避免硬扛错误
靠 @ 抑制只是“掩盖”,真正健壮的做法是提前验证:目标目录是否存在、是否可写。否则即使静默了,文件也根本建不出来。
常见漏掉的点是父目录不存在——file_put_contents('cache/a/b/c.txt', '') 会失败,因为 cache/a/b/ 可能压根没建。
立即学习“PHP免费学习笔记(深入)”;
- 用
dirname($path)提取目录部分,再用is_dir()和is_writable()双重判断 - 必要时递归创建目录:
mkdir(dirname($path), 0755, true)—— 第三个参数true启用递归 - 注意权限:Linux 下
0755通常够用;Windows 忽略该参数,但 PHP 仍要求传入
用 error_reporting(0) 全局关错?别这么干
有人试过在创建文件前调 error_reporting(0),完事再恢复。这看似“静默”,实际问题很大:
采用 php+mysql 数据库方式运行的强大网上商店系统,执行效率高速度快,支持多语言,模板和代码分离,轻松创建属于自己的个性化用户界面 v3.5更新: 1).进一步静态化了活动商品. 2).提供了一些重要UFT-8转换文件 3).修复了除了网银在线支付其它支付显示错误的问题. 4).修改了LOGO广告管理,增加LOGO链接后主页LOGO路径错误的问题 5).修改了公告无法发布的问题,可能是打压
- 它会屏蔽**当前脚本后续所有错误**,包括你没预料到的 Notice 或 Fatal
- 多线程或并发请求下,
error_reporting是进程级设置,可能污染其他逻辑 - 与
@相比,粒度太粗,且无法和try/catch配合(PHP 的错误不是 Exception)
除非你写的是 CLI 脚本且全程只干这一件事,否则不推荐。
写入失败后怎么知道原因?用 error_get_last() 捕获最后一次错误
@ 让错误不显示,但也让你失去上下文。想调试又不想开全局报错,可以在调用后立刻查最后错误:
$fp = @fopen('tmp/test.log', 'w');
if ($fp === false) {
$err = error_get_last();
// $err['message'] 就是被 @ 压住的那条 Warning 文本
error_log('文件创建失败:' . $err['message']);
}
这个技巧特别适合线上环境:既不暴露错误给用户,又能把真实原因记进日志。
注意:error_get_last() 只返回最近一次错误,且仅限于被 @ 抑制的运行时错误(Parse Error 不行),调用时机必须紧接在可疑语句之后。










