
本地 XAMPP(PHP 8.1)运行正常,但部署到服务器(PHP 7.4)后 fgets() 循环仅执行一次——根本原因是 PHP 版本差异导致的函数兼容性问题,尤其是 str_contains() 在 PHP 7.4 中不可用。
本地 xampp(php 8.1)运行正常,但部署到服务器(php 7.4)后 `fgets()` 循环仅执行一次——根本原因是 php 版本差异导致的函数兼容性问题,尤其是 `str_contains()` 在 php 7.4 中不可用。
该问题表面表现为“只读第一行”,实则并非文件读取逻辑失效,而是因调用不存在的函数(str_contains())触发了 致命错误(Fatal Error),导致脚本在首次循环后立即中止,feof() 检查虽未报错,但后续代码不再执行,给人“卡在第一行”的错觉。
? 根本原因分析
str_contains($haystack, $needle) 是 PHP 8.0 引入的原生函数。你的本地环境为 PHP 8.1,而生产服务器运行的是 PHP 7.4 —— 此版本中该函数完全不存在,调用时会抛出:
Fatal error: Uncaught Error: Call to undefined function str_contains()
由于错误未被显式捕获且错误报告可能被禁用(如 display_errors = Off),页面静默失败,仅完成第一次迭代便终止。
✅ 解决方案:兼容 PHP 7.4 的字符串检测
将所有 str_contains() 替换为 strpos() 兼容写法:
立即学习“PHP免费学习笔记(深入)”;
// ❌ PHP 8.0+ only
if (str_contains($foglalasok[$darabszam][8], "nem foglalhato")) { ... }
// ✅ 兼容 PHP 7.4+
if (strpos($foglalasok[$darabszam][8], "nem foglalhato") !== false) { ... }
// 同理替换其他两处:
} else if (strpos($foglalasok[$darabszam][8], "elutasitva") !== false) { ...
} else { ...? 提示:strpos() 返回 0 表示子串在开头,因此必须用 !== false 严格比较,避免 0 == false 导致误判。
?️ 进阶建议:增强健壮性
-
启用错误报告(开发阶段)
在脚本开头临时添加,便于快速定位问题:error_reporting(E_ALL); ini_set('display_errors', 1); -
安全关闭文件句柄
使用 try...finally 或检查 fopen() 返回值,避免资源泄露:$file = fopen("foglalasi_adatok/foglalodb.txt", 'r'); if (!$file) { throw new RuntimeException("Cannot open file"); } try { // ... 读取逻辑 } finally { fclose($file); } -
推荐替代方案:使用 file() 函数
更简洁、自动处理换行符差异(Windows \r\n vs Unix \n):$lines = file("foglalasi_adatok/foglalodb.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach ($lines as $line) { $parts = explode(';', $line); // 处理 $parts... }
? 注意事项
- 换行符差异已非主因:虽然 Unix/Linux 与 Windows 的 EOL(\n vs \r\n)不同,但 fgets() 在 PHP 各版本中均能正确识别 \n 作为行结束符;问题核心是函数缺失引发的中断。
- 始终检查 PHP 版本:通过 phpinfo() 或 echo PHP_VERSION; 确认生产环境版本,并在开发时使用与线上一致的 PHP 版本(如 Docker 或本地多版本管理工具)。
- 避免隐式依赖新特性:在团队协作或跨环境部署前,使用 PHP Compatibility Checker 等工具扫描代码兼容性。
修复 str_contains() 后,原始 while (!feof($file)) 循环即可正常遍历全部行——无需修改文件编码、权限或服务器配置。



















