php错误日志中若出现fatal error、parse error或高频warning,通常表明存在代码缺陷、攻击尝试或扫描行为;需结合nginx/apache错误日志、php-fpm slow.log及自定义应用日志交叉分析,并统一日志时区以精准定位问题。

看 PHP 错误日志里有没有 Fatal error、Parse error 或高频 Warning
PHP 自身错误日志(如 /var/log/php_errors.log)是第一道过滤器。正常访问几乎不会触发 Fatal error 或 Parse error;一旦出现,基本可判定为代码缺陷或攻击尝试(比如文件包含时路径被篡改导致解析失败)。Warning 单次出现可能是疏忽,但同一 IP 在 5 分钟内反复触发 include(): failed to open stream 或 file_get_contents(): php_network_getaddresses,大概率是扫描行为。
-
display_errors=Off必须开启,否则错误会回显到页面,反而掩盖真实日志线索 - 注意
error_reporting配置:生产环境用E_ALL & ~E_NOTICE,避免Notice级别噪音干扰关键信号 - 如果日志里大量出现
Undefined variable $xxx且集中在某个 URL 参数上(如?id=1' OR 1=1--),说明攻击者在试探 SQL 注入点
比对 Nginx access.log 和 PHP 错误日志的时间戳与请求路径
单看某一方日志容易误判。比如一个 POST /login.php 返回 200,看起来正常,但如果同一时间 PHP 日志里有 mysqli_query(): MySQL server has gone away,就说明后端连接异常,可能正被暴力破解或连接池耗尽。
- 用
awk快速对齐两份日志:先从access.log抽出异常状态码(如 403、499、500)和可疑路径,再查对应秒级时间窗口内的 PHP 错误内容 - 特别关注
GET请求却携带长参数(如?a=...&b=...超过 2KB)、或POST请求体为空但 Content-Length > 0 —— 这类请求在 Nginx 日志里存在,但在 PHP 中往往根本没走到脚本执行,而是被拦截或解析失败 - 如果 Nginx 记录了
414 Request-URI Too Large,而 PHP 日志完全空白,说明攻击载荷卡在 Web 服务器层,还没进 PHP 解析流程
检查自定义日志中是否出现未授权的敏感操作标记
应用层埋点日志(比如记录登录、密码重置、权限变更)才是真正区分“行为是否异常”的核心依据。不能只依赖系统级日志。
- 在关键函数入口加判断:比如
resetPassword()执行前,记录$_POST['email']和$_SERVER['REMOTE_ADDR'],后续发现同一 IP 1 小时内调用 20 次,且邮箱域名各不相同,就是典型撞库行为 - 避免记录明文密码或 token,但必须记录操作类型、目标 ID、用户上下文(如
HTTP_X_USER_IDheader)和响应结果(成功/失败/验证码错误) - 如果自定义日志里频繁出现
user_id=0或user_id=null触发了管理员接口(如/api/v1/users/123/delete),说明身份认证逻辑被绕过
注意 PHP-FPM 的 slow.log 和 error.log 里的进程级异常
PHP-FPM 日志不是“请求日志”,而是进程运行态快照。这里藏匿着更隐蔽的异常:比如某次请求没报错,但耗时 12 秒,slow.log 里会记录完整堆栈 —— 很可能是死循环、未设超时的 cURL 调用,或是攻击者故意触发的资源耗尽型 DoS。
-
slow.log默认只记录超过request_slowlog_timeout的请求,建议设为 3s,并确保slowlog = /var/log/php-fpm-slow.log可写 -
php-fpm.error.log出现WARNING: [pool www] child 12345 exited on signal Segmentation fault (11),基本可锁定是扩展冲突或内存破坏,不是普通业务异常 - 如果多个 worker 进程在相近时间集体重启(
ERROR: failed to ptrace(ATTACH)类错误),要怀疑是否被注入恶意.so 或遭遇提权攻击
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











