PHP读取文件查MySQL结果顺序异常及写入文件失败求助
问题解决:PHP逐行读取文件查询MySQL并按顺序写入结果
让我们一步步解决你遇到的两个核心问题:
一、结果顺序混乱 + 加引号后无输出
问题根源
字段类型不匹配导致错误匹配
你的code字段应该是字符串类型(因为存在带前导零的取值,比如0000000000000001),但你最初的查询code=$line会让MySQL自动做类型转换:把字符串类型的code转成数字,同时把$line也转成数字。这就导致'0000060025909170'和60025909170被判定为相等,所以查询第一行的60025909170时,意外返回了原文件第32000行对应记录的结果,直接打乱了顺序。换行符破坏查询条件
file()函数读取每行时会保留末尾的换行符(\n),当你给$line加引号后,查询条件变成了code='60025909170\n'——数据库里根本不存在带换行符的code值,自然查不到任何结果。
修复方案
- 读取每行后用
trim()移除换行符、空格等无效空白字符; - 对字符串类型的字段,必须用引号包裹变量,同时使用预处理语句(避免SQL注入,同时保证查询语法正确)。
二、写入文件仅一行或无输出
问题根源
- 用
fopen($outfile, 'w')时,每次打开都会清空文件内容,循环结束后只会保留最后一次写入的结果; file_put_contents()默认是覆盖模式,同样会清空之前的内容。
修复方案
- 使用追加模式打开文件(
fopen($outfile, 'a')),或者给file_put_contents()加上FILE_APPEND参数; - 推荐提前打开输出文件,循环内只做写入操作,减少IO开销。
完整修正代码
<?php // 假设你已经完成了数据库连接初始化 $conn 和 $db_table 定义 $infile = '/root/prcode'; $outfile = '/path/to/your/output.txt'; // 替换成你的输出文件路径 // 提前打开输出文件(追加模式),避免循环内重复打开关闭 $fp = fopen($outfile, 'a'); if (!$fp) { die("无法打开输出文件"); } // 读取文件,自动跳过空行并移除换行符 $lines = file($infile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); // 使用预处理语句,避免SQL注入+保证字符串字段查询语法正确 $stmt = mysqli_prepare($conn, "SELECT * FROM $db_table WHERE code = ?"); mysqli_stmt_bind_param($stmt, "s", $code); // "s" 表示参数为字符串类型 foreach ($lines as $line) { // 清理行内容,去掉前后所有空白字符 $code = trim($line); // 跳过无效行(比如原文件里的*、.开头的行,可根据你的需求调整过滤规则) if (empty($code) || !ctype_digit($code)) { continue; } // 执行预处理查询 mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); // 处理并写入查询结果 while ($row = mysqli_fetch_array($result, MYSQLI_NUM)) { // 用implode自动拼接字段,替代手动写13个字段更简洁 $out = implode(',', $row) . "\n"; fwrite($fp, $out); // 可选:同时输出到控制台查看进度 echo $out; } } // 关闭所有资源,避免内存泄漏 mysqli_stmt_close($stmt); fclose($fp); mysqli_close($conn); ?>
代码关键优化点
- 用
FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES读取文件,自动处理换行符和空行; - 预处理语句彻底解决了字符串字段查询的语法问题,同时杜绝SQL注入风险;
- 提前打开输出文件,减少循环内重复IO操作的开销;
- 增加无效行过滤逻辑,避免对非数字的行做无效查询;
- 用
implode(',', $row)替代手动拼接字段,降低代码维护成本。
内容的提问来源于stack exchange,提问作者NovaOrsa
相关产品推荐
相关产品推荐

