PHP写入文本文件时数据重复且无换行问题排查求助
PHP写入日志重复且无法换行问题排查
故障原因分析
1. 换行符未正确生成
写入日志时,你在$log_content中手动输入的换行在双引号字符串里可能被解析为空格,且未考虑系统差异(Windows需\r\n,Linux仅\n),导致两次写入的日志内容直接拼接,无法分隔,最终日志文件里没有有效换行符。
2. 日志读取的feof陷阱
viewer.php中使用while (!feof($file_handle))配合fgets的逻辑存在问题:当fgets读取到最后一行后,文件指针并未到达EOF,循环会再执行一次,此时fgets返回false,explode后无法获取有效索引值,导致出现空内容的重复行。
3. 代码可能被重复触发
日志中两次记录的时间完全一致,说明写入日志的代码被执行了两次(比如页面重复刷新、AJAX请求重复发送等),叠加换行问题后,日志内容直接连在一起。
额外风险:SQL注入
原代码中直接将$id拼入SQL语句,存在严重的SQL注入风险,同时未处理查询结果为空的情况,可能导致$nmdl未定义。
修复方案
1. 修复写入时的换行问题
使用PHP内置常量PHP_EOL自动适配系统换行符,替换手动换行:
$log_content = "$tgl|$jam|menghapus data $nmdl" . PHP_EOL;
2. 修复读取逻辑的feof问题
修改循环逻辑,直接判断fgets的返回值,同时增加数组长度检查避免报错:
<?php $file_handle = fopen("Timeline/Logline.txt", "rb"); while ($line_of_text = fgets($file_handle)) { $parts = explode('|', $line_of_text); if (count($parts) >= 3) { $lna = trim($parts[0]); $lnb = trim($parts[1]); $lnc = trim($parts[2]); echo "$lna $lnb $lnc <br>"; } } fclose($file_handle); ?>
3. 修复SQL注入及空值问题
使用预处理语句执行查询,并处理查询结果为空的情况:
$id = trim(strip_tags($_GET['id'])); // 预处理查询 $slnmdl = "select nama from $tabname where ID=?"; $stmt = mysqli_prepare($conn, $slnmdl); mysqli_stmt_bind_param($stmt, "s", $id); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); $row = mysqli_fetch_assoc($result); $nmdl = $row['nama'] ?? ''; // 为空时赋值空字符串
4. 排查重复执行原因
检查触发写入日志的请求是否被重复发送:
- 表单提交可增加防重复token
- AJAX请求添加防抖处理
- 避免页面重复刷新
内容的提问来源于stack exchange,提问作者otw adoh
相关产品推荐
相关产品推荐

