【问题标题】:php - Piping input to perl process automatically decodes url-encoded stringphp - perl 进程的管道输入自动解码 url 编码的字符串
【发布时间】: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


【解决方案1】:

自我提醒:始终检查您的假设。事实证明,在我的数亿行输入中的某个地方,实际上应该有 url 编码的空格。找到它们需要一段时间,因为有数亿个正确的文字空格,但它们确实存在。

对不起各位!

【讨论】:

    猜你喜欢
    • 2016-05-12
    • 2012-10-09
    • 1970-01-01
    • 1970-01-01
    • 2013-04-01
    • 2016-05-31
    • 2012-10-17
    • 2015-04-13
    • 2011-11-26
    相关资源
    最近更新 更多