在PHP中重定向I/O
为什么到新STDOUT的重定向隐式工作,而从新STDIN的重定向必须显式发生?原始STDIN、STDOUT和STDERR是PHP中的系统常量。它们由PHP初始化时的标准输入、输出和错误的文件描述符资源填充 php.net文档描述了以下有关常量中资源的内容: 常数的值;只允许使用标量值和空值。 标量值是整数、浮点、字符串或布尔值。它是 可以定义资源常量,但不建议这样做 并可能导致不可预测的行为 调用在PHP中重定向I/O,php,Php,为什么到新STDOUT的重定向隐式工作,而从新STDIN的重定向必须显式发生?原始STDIN、STDOUT和STDERR是PHP中的系统常量。它们由PHP初始化时的标准输入、输出和错误的文件描述符资源填充 php.net文档描述了以下有关常量中资源的内容: 常数的值;只允许使用标量值和空值。 标量值是整数、浮点、字符串或布尔值。它是 可以定义资源常量,但不建议这样做 并可能导致不可预测的行为 调用fclose(STDOUT)时,文件描述符资源将关闭并与STDOUT常量分离。与常量的默认行为相反,
fclose(STDOUT)
时,文件描述符资源将关闭并与STDOUT常量分离。与常量的默认行为相反,STDOUT常量被更改
当一个字符串像echo“Hello,World!”
那样被回送时,PHP将不使用STDOUT常量,但它将从操作系统实时查询当前的“standard out”文件描述符。此外,一旦标准输出常量被fclose'd,它本身就变得不可用。即使像fwrite(STDOUT,“hello”)
这样的语句也不会起作用
为标准输出配置新文件描述符时,此新文件描述符将方便地放入$STDOUT
。请注意,这是一个变量,而不是常量。根据定义,在PHP中不可能重新定义常量,系统常量STDOUT在这里也不例外。目前无法将新文件描述符重新分配给标准输出常量
最后,为了使这项工作更直观,PHP团队应该考虑使用便利功能来重新分配这些文件描述符,或者至少使系统常量更像“魔术常数”。从某种意义上说,它们会自动计算为实际的文件描述符。
我在阅读代码片段时首先看到的是,首先尝试关闭STDIN、STDOUT等的常量,然后使用同名变量打开文件;因此,您使用的值是完全不同的,$STDIN与STDIN不同。您可能可以使用define函数重新定义STDIN,但我不确定,也无法在没有计算机atm的情况下进行检查。这仅在类UNIX系统(linux等)中发生,因为当您打开文件时,UNIX使用次要文件描述符,因此在进程STDIN中,STDOUT和STDERR始终为0、1和2。 执行此操作时:<?php
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
$STDIN = fopen("/tmp/some-named-pipe", "r");
$STDOUT = fopen("/tmp/foo.out", "wb");
$STDERR = fopen("/tmp/foo.err", "wb");
echo "Hello, World!"; // goes to /tmp/foo.out, implied STDOUT
fscanf($STDIN, "%s\n", $top_secret); // explicit $STDIN, cant use STDIN
?>
您正在关闭STDIN(0)、STDOUT(1)和STDERR(2),因此当您以相同的顺序打开文件时,它们会得到0、1和2作为文件描述符。如果在windows上运行相同的代码,它将无法工作。这是多次重定向标准输出的示例。 STDOUT的关闭第一次有效,但下一次有效 需要关闭$STDOUT
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
$STDIN = fopen("/tmp/some-named-pipe", "r");
$STDOUT = fopen("/tmp/foo.out", "wb");
$STDERR = fopen("/tmp/foo.err", "wb");
输出没有为我转到/tmp/foo.out
。你使用的是什么版本的PHP?我根本找不到任何文档来解释你所说的$STDOUT行为。您的$STDOUT
语法来自哪里?来自:
<?php
# Redirecting 10 times ...
# Need to close 'STDOUT' & '$STDOUT', otherwise the 2nd time
# the redirecting fails.
for ( $i = 1; $i <= 10; $i++ )
{
$sLogName = sprintf("reopen_%02d.log", $i);
echo "Redirecting to '" . $sLogName . "' ...\n";
fclose(STDOUT);
fclose($STDOUT); # Needed for reopening after the first time.
$STDOUT = fopen($sLogName, "w");
echo "Now logging in file '" . $sLogName . "' ...\n";
}
?>