【发布时间】:2010-10-07 23:21:24
【问题描述】:
我知道 PHP 通常用于 Web 开发,其中 没有标准输入,但 PHP 声称可以用作通用脚本语言,如果您确实遵循它是基于网络的时髦语言公约。我知道 PHP 使用 print 和 echo 打印到 stdout(或任何你想调用的名称),这很简单,但我想知道 PHP 脚本如何从 stdin 获取输入(特别是fgetc(),但任何输入功能都很好),或者这甚至可能吗?
【问题讨论】:
我知道 PHP 通常用于 Web 开发,其中 没有标准输入,但 PHP 声称可以用作通用脚本语言,如果您确实遵循它是基于网络的时髦语言公约。我知道 PHP 使用 print 和 echo 打印到 stdout(或任何你想调用的名称),这很简单,但我想知道 PHP 脚本如何从 stdin 获取输入(特别是fgetc(),但任何输入功能都很好),或者这甚至可能吗?
【问题讨论】:
可以通过创建php://stdin 的文件句柄来读取stdin,然后使用fgets() 从其中读取一行(或者,如您已经说过的,fgetc() 用于单个字符):
<?php
$f = fopen( 'php://stdin', 'r' );
while( $line = fgets( $f ) ) {
echo $line;
}
fclose( $f );
?>
【讨论】:
fcloseSTDIN了吗?
从STDIN读取的是recommended way
<?php
while (FALSE !== ($line = fgets(STDIN))) {
echo $line;
}
?>
【讨论】:
为避免弄乱文件句柄,请使用file_get_contents() 和php://stdin:
$ echo 'Hello, World!' | php -r 'echo file_get_contents("php://stdin");'
Hello, World!
(如果您正在从 stdin 读取大量数据,您可能希望使用文件句柄方法,但这应该适用于数兆字节。)
【讨论】:
一个简单的方法是
$var = trim(fgets(STDIN));
【讨论】:
一口气搞定:
$contents = file_get_contents("php://stdin");
echo $contents;
【讨论】:
您可以在php://stdin 上使用fopen():
$f = fopen('php://stdin', 'r');
【讨论】:
这也有效:
$data = stream_get_contents(STDIN);
【讨论】:
IIRC,您还可以使用以下内容:
$in = fopen(STDIN, "r");
$out = fopen(STDOUT, "w");
技术上相同,但语法更简洁。
【讨论】:
使用 fgets 时,如果 stdin 未设置或为空,它可能会在 bash 脚本中阻塞,包括在使用 @ php error control operator 时。
#!/usr/bin/php
<?php
$pipe = @trim(fgets(STDIN));
// Script was called with an empty stdin
// Fail to continue, php warning
可以通过在 php 标头上设置 stream_set_blocking 来避免这种行为:
#!/usr/bin/php
<?php
stream_set_blocking(STDIN, false);
$pipe = @trim(fgets(STDIN));
// Script was called with an empty stdin
// No errors or warnings, continue
echo $pipe . "!";
例如,调用如下:
echo "Hello world" | ./myPHPscript
// Output "Hello world!"
./myPHPscript
// Output "!"
【讨论】:
declare(strict_types=1);指令时,值得注意的是,将stream_set_blocking的第二个参数设置为0会导致错误,因为这个函数期望它的第二个参数是一个有效的布尔值,当提供整数时。请改用stream_set_blocking(STDIN, false);。
如果您只想读取一行而不是手动打开 STDIN 流,请使用内置的 readline() 函数而不是太多麻烦:
<?php
$age= readline("Enter your age: ");
echo "Your age is : ".$age;
PHP 文档是您的朋友: https://www.php.net/manual/en/function.readline.php
【讨论】: