解析大型文本文件时,Perl在从PHP运行时会崩溃


Parse large text file with Perl crashes when run from PHP

我正在使用Perl脚本来解析和创建JSON输出以供PHP使用。

基本上,我使用Perl解析大型文本文件(5-20MB),数据如下:

XXXXXXYYYYYYYYYYYYYZZZZZZZZZYYYYYYYYYPPPPPPPPPPP
XXXXXXYYYYYYYYYYYYYZZZZZZZZZYYYYYYYYYPPPPPPPPPPP
XXXXXXYYYYYYYYYYYYYZZZZZZZZZYYYYYYYYYPPPPPPPPPPP
XXXXXXYYYYYYYYYYYYYZZZZZZZZZYYYYYYYYYPPPPPPPPPPP

脚本打印文件中每行数据的JSON输出:

{ "1" : "XXXXXXYYYYYYYYYYYYYZZZZZZZZZYYYYYYYYYPPPPPPPPPPP", "2": ... } 

当从终端运行时,它在1.5秒内超过100,000行这样的文件,成功创建JSON。

但是当我在PHP中使用

运行脚本时
exec("/usr/bin/perl script.pl input_file.txt",$output);
print_r(json_decode($output[0],true);

坠毁。虽然,如果我给它文件2000-3000行,它工作得很好。不使用json_decode,只执行$output变量的var_dump也可以。

我认为它与json_decode有关。

还有其他方法吗?建议吗?解决方案?

注。我已经将PHP的memory_limit增加到128MB。

谢谢。编辑:

Perl脚本:

#!/usr/bin/perl -w
use strict;
use warnings;
my $file = $ARGV[0];
my $id = 0;
open my $info, $file or die "Could not open $file: $!";
print "{";
while( my $line = <$info>)  {
    print "'"$id'" : " . "'"" . trim($line) . "'"";
    print ',' unless eof;
    $id++;
}
print "}";
sub trim {
    (my $s = $_[0]) =~ s/^'s+|'s+$//g;
    return $s;        
}
close $info;

错误似乎是在你的php.ini文件。它控制PHP安装的一系列可配置选项。您的问题很可能如下:

; Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 1M

这只是一个例子。但事实似乎是,你的记忆极限太小了。试着把它增加到更大的值,看看是否能解决问题。例如:

; Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 56M

还要注意,任何时候编辑ini文件,都必须重新启动PHP服务器才能应用ini更改。这是一个很容易忘记的步骤,可能会导致严重的挫折。

如果从控制台运行,则错误存在于php-config中。这可能是各种配置错误,从脚本执行超时到内存问题或脚本执行权限。在您的情况下,我保证会发生一些超时或脚本执行权限,具体取决于崩溃所需的时间。

我认为这可以在纯PHP中完成,但我只会专注于您所遇到的错误

你得到Server Error" HTTP 500.的原因是因为你没有启用错误报告。尝试切换错误报告,你会发现$output返回空数组,因此$output[0]无效,参见PHP调用类返回错误:500

使用exec时,确保使用完整路径

$buid = 'FULL PATH TO /script.pl' ;
$input = 'FULL PATH TO /input_file.txt' ;
exec("$buid $input",$output);
print_r($output);

输出
Array
(
    [0] => Ok{"0" : "XXXXXXYYYYYYYYYYYYYZZZZZZZZZYYYYYYYYYPPPPPPPPPPP","1" : "XXXXXXYYYYYYYYYYYYYZZZZZZZZZYYYYYYYYYPPPPPPPPPPP","2" : "XXXXXXYYYYYYYYYYYYYZZZZZZZZZYYYYYYYYYPPPPPPPPPPP","3" : "XXXXXXYYYYYYYYYYYYYZZZZZZZZZYYYYYYYYYPPPPPPPPPPP"}
)

你不需要/usr/bin/perl在你的执行,因为你的脚本已经开始的#!/usr/bin/perl -w