fgetcsv
我有一个 PHP 脚本,它通过 PHP 的包装器读取文件zip://
。它在本地和通过 cron 作业在生产环境中运行时都运行良好。但是,当通过 CLI 在生产环境中调用时,它会因分段错误而失败,显然是在读取文件结束时fgetcsv
返回的false
。
脚本的相关部分:
#!/usr/local/bin/php5
<?php
...
$i = 0;
while (($row = fgetcsv($file)) !== false) {
// processing ...
if (++$i % 50000 == 0) {
echo '.';
}
}
printf("\nFinished reading %s records.\n\n", number_format($i));
fclose($file);
其输出如下:
-bash-3.00$ ./script.php
Reading file.zip................Segmentation fault
它似乎在printf
读取所有记录之前但之后发生了段错误,所以我怀疑它在到达文件末尾时失败了。
-bash-3.00$ /usr/local/bin/php5 -v
PHP 5.2.8 (cli) (built: Apr 14 2010 16:08:06)
Copyright (c) 1997-2008 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies
with the ionCube PHP Loader v3.1.31, Copyright (c) 2002-2007, by ionCube Ltd.
这可能是什么原因造成的?有什么方法可以解决吗?
答案1
strace
proc 来找出它死在哪里。段错误在定义上是一种未处理的错误,因此日志不太可能告诉你太多有趣的信息。推测:php 针对已部署到的主机上不可用的共享库进行编译。
或者,既然你说你在共享主机上运行,为什么不让供应商的支持渠道参与进来呢?他们可以利用 root 权限做更多的事情来查明发生了什么,而他们提供的环境有问题。
答案2
您需要检查日志并查看出错的位置。您可能需要在 php.ini 文件中启用日志记录。
您可能没有该文件的适当权限。当您将其作为 cron 运行时,您可能以 root 身份运行该脚本(假设您在系统 crontab 中有 cron)。
因此,请检查您的日志并确保您的文件具有正确的权限,可以以您通过 CLI 登录的用户身份运行。
答案3
我在使用时遇到了同样的问题#!/usr/bin/php -q
。我使用 fpdf.org 创建 pdf。我使用 PHPfile
命令读取整个文件(39000 行),但遇到了同样的段错误。我将文件命令替换为 fopen 和 fgets,逐行读取,问题就解决了。我怀疑这个段错误来自 bash,因为当我手动运行php -q mpdf.php
而不是在第一行./mpdf
使用#!/usr/bin/php
时,问题没有发生。顺便说一下,我在 SUSE linux 8.2 上运行 PHP 4.3.1。出于多种原因,我必须保留那里,而不是移动到更高版本。
希望对您有所帮助。来自阳光灿烂的雅典(希腊)的问候
克里斯托斯·米凯尔