将数据通过管道传输到命令行 php?

问题描述 投票:0回答:10

可以使用unix管道将数据传输到命令行php脚本中吗?我试过了

$> data | php script.php

但是预期的

data
并没有出现在
$argv
中。有办法做到这一点吗?

php command-line pipe
10个回答
52
投票

PHP 可以从标准输入读取,并且还提供了一个很好的快捷方式:

STDIN

有了它,您可以使用诸如

stream_get_contents
之类的东西来执行以下操作:

$data = stream_get_contents(STDIN);

这只会将所有管道数据转储到

$data

如果您想在读取所有数据之前开始处理,或者输入大小太大而无法放入变量中,您可以使用:

while(!feof(STDIN)){
    $line = fgets(STDIN);
}

STDIN
只是
$fh = fopen("php://stdin", "r");
的快捷方式。 相同的方法可以应用于读写文件、tcp 流。


29
投票

据我了解,

$argv
将显示程序的参数,换句话说:

php script.php arg1 arg2 arg3

但是如果将数据通过管道传输到 PHP,则必须从标准输入读取它。我从未尝试过这个,但我认为是这样的:

$fp = readfile("php://stdin");
// read $fp as if it were a file

20
投票

如果您的

data
位于类似的位置,您还可以使用 -F 或 -R 标志(-F 读取并执行其后面的文件,-R 按字面意思执行它)。通过管道输入将出现在(常规)全局变量 $argn

简单的例子:

echo "hello world" | php -R 'echo str_replace("world","stackoverflow", $argn);'

4
投票

你可以通过管道输入数据,是的。但它不会出现在

$argv
中。它将转到标准输入。您可以通过多种方式阅读本文,包括
fopen('php://stdin','r')

手册中有很好的例子


4
投票

这对我有用:

stream_get_contents(fopen("php://stdin", "r"));

3
投票

看到这篇文章,希望制作一个行为类似于 shell 脚本的脚本,为输入的每一行执行另一个命令...例如:

ls -ln | awk '{print $9}'

如果你想制作一个行为类似的 php 脚本,这对我有用:

#!/usr/bin/php
<?php

$input = stream_get_contents(fopen("php://stdin", "r"));

$lines = explode("\n", $input);

foreach($lines as $line) {
    $command = "php next_script.php '" . $line . "'";
    $output = shell_exec($command);
    echo $output;
}

2
投票

如果您希望它出现在

$argv
中,请尝试以下操作:

echo "Whatever you want" | xargs php script.php

这会将标准输入中的任何内容隐藏到命令行参数中。


1
投票

最好的选择是使用 -r 选项并从标准输入中获取数据。即我使用它可以使用 PHP 轻松解码 JSON。 这样您就不必创建物理脚本文件。

事情是这样的:

docker inspect $1|php -r '$a=json_decode(stream_get_contents(STDIN),true);echo str_replace(["Array",":"],["Shares","  -->  "],print_r($a[0]["HostConfig"]["Binds"],true));'

这段代码将显示主机和容器之间的共享文件夹。 请将 $1 替换为容器名称或将其放入 bash 别名中,例如 ie displayshares() { ... }


1
投票

我需要获取 CSV 文件并将其转换为 TSV 文件。当然,我可以将文件导入 Excel,然后重新导出,但是通过转换器传输数据意味着我可以留在命令行中轻松完成工作,这有什么乐趣!

所以,我的脚本(称为

csv2tsv
)是

#!/usr/bin/php
<?php
while(!feof(STDIN)){
    echo implode("\t", str_getcsv(fgets(STDIN))), PHP_EOL;
}

chmod +x csv2tsv
.

然后我可以运行它

cat data.csv | csv2tsv > data.tsv
,我现在将数据作为 TSV!

好的。没有错误检查(数据是实际的 CSV 文件吗?)等,但原理很好。

当然,您可以根据需要链接任意数量的命令。

如果您想要更多地扩展这个想法,那么在您的命令中包含其他选项怎么样?

简单!

#!/usr/bin/php
<?php
$separator = $argv[1] ?? "\t";
while(!feof(STDIN)){
    echo implode($separator, str_getcsv(fgets(STDIN))), PHP_EOL;
}

现在我可以将默认分隔符从制表符覆盖为其他内容。

|
也许吧!

cat data.csv | csv2tsv '|' > data.psv

希望这对您有所帮助,并让您看到自己还能做多少事情!


0
投票

也可以通过

STDIN
喂食。

echo 'Hi <?php echo getenv()["USER"];?>!' | php

php <<< 'Hi <?php echo getenv()["USER"];?>!' 

将文件输入 STDIN:

cat code.php | php

php <<< $(cat somehtml.html)
© www.soinside.com 2019 - 2024. All rights reserved.