PHP使用fopen操作文件时出现相同行重复写入、内容错乱问题
异常根因分析
- 文件操作顺序完全错误:你先执行
fopen($file, "w"),w模式会直接清空目标文件内容,后续调用file($file)读取到的已经是被清空的空文件,仅首次执行可能因为操作系统缓存还能读到残留内容,后续执行读取内容全为空,直接导致内容错乱。正确顺序应该是先读取全部文件内容,再打开文件写入。 $newline变量未重置:遍历每一行前没有清空$newline的旧值,每次处理行都会在之前的内容后追加,最终导致行内容重复、不断累积变长。- 只有删除逻辑,没有新增逻辑:当前代码仅实现了
str_replace移除存在的[$added],完全没有判断如果目标位置不存在[$added]时的新增逻辑,自然不可能实现「存在则删、不存在则加」的切换效果。 - 正则使用错误且冗余:
preg_match("~\b$details[0]\b~", 3)参数顺序完全写反(preg_match参数顺序为正则, 待匹配字符串),这里只是要匹配行ID为3的行,直接判断$details[0] == 3即可,完全不需要用正则匹配。 - 字段拼接丢失分隔符:处理索引为5的字段时,替换完成后没有补上
||分隔符,直接导致该字段和后面的字段内容拼接在一起,出现[100][200]55.183.567这类格式错误。
修正后代码示例
$added = $_GET['added']; //100 for this example $file = '你的目标文件路径'; // 补全你实际的文件路径 // 先读取全部文件内容,忽略行末换行符避免拼接重复 $list = file($file, FILE_IGNORE_NEW_LINES); $newContent = []; foreach ($list as $line) { $details = explode("||", $line); // 匹配行ID为3的目标行,可根据需求修改为动态匹配规则 if ($details[0] == 3) { $targetField = $details[5] ?? ''; $tag = "[" . $added . "]"; if (strpos($targetField, $tag) !== false) { // 存在目标值则删除 $details[5] = str_replace($tag, "", $targetField); } else { // 不存在目标值则添加 $details[5] .= $tag; } } // 重新拼接为标准格式行 $newContent[] = implode("||", $details); } // 一次性写入全部内容,避免逐行写入的错乱问题 file_put_contents($file, implode("\n", $newContent));
内容的提问来源于stack exchange,提问作者Cain Nuke
相关产品推荐
相关产品推荐

