
用 error_log() 记录变量最简单但容易丢数据
直接调用 error_log() 是 PHP 写日志最快的方式,但它默认写到 Web 服务器错误日志(如 Apache 的 error.log),不是你项目目录下的日志文件,而且不支持自动格式化数组或对象。
- 如果没改过 PHP 配置,
error_log('hello')会进系统级日志,你可能根本找不到它 -
error_log()对array或object直接输出Array或Object字符串,看不出内容 - 想写到自定义文件?必须加第三个参数
true,并确保路径可写:error_log(print_r($data, true), 3, '/var/log/myapp.log') - 注意:
print_r($data, true)是必须的,漏掉true会直接输出到页面,不进日志
用 file_put_contents() 控制日志位置和格式
比 error_log() 更可控,适合写到项目内日志文件(比如 logs/debug.log),还能自己拼时间、变量名、换行。
- 务必加
FILE_APPEND | LOCK_EX标志,否则并发写入会覆盖或错乱:file_put_contents('logs/debug.log', date('Y-m-d H:i:s') . " DEBUG: " . print_r($var, true) . "\n", FILE_APPEND | LOCK_EX) - 路径要相对或绝对——如果用相对路径,是以当前执行脚本为基准,不是
__DIR__;建议统一用__DIR__ . '/../logs/debug.log' - 别忘了手动创建
logs/目录并设好权限(Web 进程得有写权限),否则静默失败 - 大数组或对象慎用
print_r(),嵌套深时可能卡住或超内存;可先用is_array()判断,再限制递归深度
调试时用 var_export() 替代 print_r() 更安全
var_export() 输出的是合法 PHP 代码,适合记录需要后续反解的变量(比如配置快照),也比 print_r() 少一些不可见字符干扰。
-
var_export($data, true)返回字符串,false会直接输出,又会打到页面上 - 对
resource类型(如文件句柄、数据库连接)会报错,得提前过滤:!is_resource($data) ? var_export($data, true) : 'resource_' . get_resource_type($data) - 它不处理闭包(
Closure),遇到就崩,得加is_object($data) && $data instanceof Closure判断 - 输出里带单引号和换行,写进日志时建议用
PHP_EOL统一换行,别混用\n
线上环境禁用裸 print_r() 和临时日志
开发时随手写的 file_put_contents(... print_r(...)) 很容易被遗忘,上线后持续刷盘、暴露敏感数据、拖慢响应。
立即学习“PHP免费学习笔记(深入)”;
- 所有日志写入前检查环境:
if (getenv('APP_ENV') === 'dev') { file_put_contents(...); } - 避免记录
$_POST、$_SERVER全量,尤其HTTP_AUTHORIZATION、PHP_AUTH_PW等字段 - 日志文件不放在 Web 可访问路径下(比如别放
public/logs/),否则可能被直接下载 - 长期运行的脚本(如 CLI)要注意日志轮转,否则单个文件会越来越大,
file_put_contents()不自动切分
真正难的不是“怎么写进去”,而是“什么时候停写”“写哪些字段”“谁有权看”,这些边界一旦模糊,日志就从帮手变成隐患。











