error_log()写入文件失败主因是权限不足、路径错误或php.ini中log_errors与error_log配置覆盖;需显式传参3、用绝对路径、检查目录可写、手动加换行和时间戳。

error_log() 写入文件失败的常见原因
直接调用 error_log() 却没看到日志写入目标文件?大概率不是函数用错了,而是 PHP 运行时没权限、路径不对,或被 log_errors 和 error_log 配置项覆盖了行为。
-
error_log()默认不写文件,只发到 SAPI 错误输出(比如 Apache 的error_log或 CLI 的 stderr);要写文件,必须显式传入第二个参数3(LOG_ERR是常量名,但这里要的是整数 3) - 目标文件路径必须是绝对路径,相对路径会以 Web 服务器工作目录(非脚本所在目录)为基准,极易写错位置
- PHP 进程用户(如
www-data或apache)必须对目标目录有写权限;用touch手动创建文件没用,得确保父目录可写 - 如果
log_errors = On且error_log = /path/to/php-error.log在 php.ini 中设置了,所有错误(包括trigger_error())都会被重定向到那个位置,你调error_log("msg", 3, "my.log")可能被静默忽略
用 error_log() 安全写入自定义日志文件的写法
别依赖默认行为,每次写文件都显式指定参数,并做基础兜底检查。
- 始终用绝对路径:用
__DIR__或dirname(__FILE__)拼接,例如error_log("user login: 123", 3, __DIR__ . "/logs/app.log") - 写之前确保目录存在且可写:
is_dir($dir) && is_writable($dir),否则error_log()会静默失败(不报错也不写) - 避免并发写乱序:PHP 的
error_log()写文件是原子的(底层用write(2)),但多进程同时写同一文件仍可能交叉;高频场景建议加锁或换用 Monolog 等库 - 注意换行:
error_log()不自动加\n,记得自己补上,否则所有日志挤在一行
error_log() 和 file_put_contents() 写日志的区别
很多人纠结该用哪个。关键看你要不要“错误上下文”和“SAPI 集成”。
-
error_log()是 PHP 原生日志入口,支持直接发到系统 syslog(参数4)、邮件(1)或 SAPI 错误流;写文件只是其中一种模式,但无格式控制、无轮转能力 -
file_put_contents()更灵活:可追加(FILE_APPEND)、可锁(LOCK_EX)、可格式化时间戳,但完全绕过 PHP 错误处理机制,调试时看不到它写的日志出现在phpinfo()的error_log配置里 - 性能差异极小,瓶颈都在磁盘 IO;但
error_log()在 CLI 模式下若未设error_logini 值,会直接输出到终端,可能污染 stdout - 线上环境建议统一走
error_log()+ 文件路径,便于和trigger_error()日志对齐;开发期临时记录可用file_put_contents()避免配置干扰
日志内容里必须包含时间戳和上下文
error_log() 自身不加时间,也不带请求 ID、文件行号——这些得你自己拼。
立即学习“PHP免费学习笔记(深入)”;
- 别写
error_log("failed"),至少写成error_log(date("Y-m-d H:i:s") . " [". basename(__FILE__) . ":" . __LINE__ . "] failed\n", 3, $path) - Web 请求中建议加入
$_SERVER["REQUEST_URI"]或自定义 trace_id(从 header 读或生成),否则排查时无法关联一次请求的多条日志 - 敏感信息过滤:不要直接
print_r($_POST, true)写日志;密码、token、手机号等字段必须脱敏,比如用preg_replace("/\d{4}/", "****", $str) - 大数组/对象别直接
var_export(),容易撑爆磁盘;用json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)更可控










