【发布时间】:2016-10-13 17:36:12
【问题描述】:
我正在使用proc_open 将一些文本传送到 perl 脚本以加快处理速度。文本包括 url 编码的字符串以及文字空格。当原始文本中出现 url 编码的空间时,它似乎在到达 perl 脚本时被解码为文字空间。在 perl 脚本中,我依赖于文字空格的定位,所以这些不需要的空格会弄乱我的输出。
为什么会发生这种情况,有没有办法防止它发生?
相关代码sn-p:
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
);
$cmd = "perl script.pl";
$process = proc_open($cmd, $descriptorspec, $pipes);
$output = "";
if (is_resource($process)) {
fwrite($pipes[0], $raw_string);
fclose($pipes[0]);
while (!feof($pipes[1])) {
$output .= fgets($pipes[1]);
}
fclose($pipes[1]);
proc_close($process);
}
一行原始文本输入看起来像这样:
key url\tvalue1\tvalue2\tvalue3
我也许可以通过转换输入格式来避免这个问题,但由于各种原因,这是不受欢迎的,并且绕过而不是解决关键问题。
此外,我知道问题发生在 php 脚本和 perl 脚本之间,因为我在将其写入 perl 脚本 STDIN 管道之前检查了原始文本(带有echo),并且我已经测试我的 perl 脚本直接在 url 编码的原始字符串上。
我现在在下面添加了 perl 脚本。它基本上可以归结为一个小型 map-reduce 工作。
use strict;
my %rows;
while(<STDIN>) {
chomp;
my @line = split(/\t/);
my $key = $line[0];
if (defined @rows{$key}) {
for my $i (1..$#line) {
$rows{$key}->[$i-1] += $line[$i];
}
} else {
my @new_row;
for my $i (1..$#line) {
push(@new_row, $line[$i]);
}
$rows{$key} = [ @new_row ];
}
}
my %newrows;
for my $key (keys %rows) {
my @temparray = split(/ /, $key);
pop(@temparray);
my $newkey = join(" ", @temparray);
if (defined @newrows{$newkey}) {
for my $i (0..$#{ $rows{$key}}) {
$newrows{$newkey}->[$i] += $rows{$key}->[$i] > 0 ? 1 : 0;
}
} else {
my @new_row;
for my $i (0..$#{ $rows{$key}}) {
push(@new_row, $rows{$key}->[$i] > 0 ? 1 : 0);
}
$newrows{$newkey} = [ @new_row ];
}
}
for my $key (keys %newrows) {
print "$key\t", join("\t", @{ $newrows{$key} }), "\n";
}
【问题讨论】:
-
echo($raw_string)在fwrite调用之前看看它说了什么 -
我已经做到了,正如我在上一段中提到的那样。不过谢谢!我会更清楚地说明我在写作之前检查了原始字符串。
-
perl 脚本有什么作用?你能展示一下它是如何读取输入数据的吗?
-
@xxfelixxx 我已将 perl 脚本添加到我的问题正文中。我之前没有添加它,因为我单独测试了脚本没有问题,但很可能我遗漏了一些东西。我是 perl 新手。
标签: php perl url-encoding piping proc-open