php - 在 PHP 中,输出缓冲区打印到哪里?打印什么东西给它?

标签 php buffer output semantics

PHP 有许多不同的打印方式,我不明白它们之间的区别。至少有以下几点:

  • 标准输出和标准错误。这些可以表示为 php://stdoutphp://stderr .还有常量STDOUTSTDERR ,我认为这些指的是同一件事。到目前为止,一切都很好;这些都是标准的。
  • php://output .这是什么?它去哪儿了?它是php://stdout的同义词吗? , 或者是其他东西? The docs说它写入“输出缓冲区机制”,但我不知道此缓冲区的内容在那之后去了哪里。
  • printecho . The docs说这些打印到 php://output .它们都是语言结构,但据推测,区别在于 print是一个表达式,但是 echo是一个声明。
  • printf和很多 friend 。做这些也去php://output
  • Escaping .有很多可供选择的转义语法,但我猜它们都具有相同的语义。但是语义是什么?转义文本打印到哪里?也给php://output ?目前,我明白?>foo<?php作为 echo 'foo'; 的语法糖;这是正确的吗?

还有更多的输出方式吗?到底有什么区别?哪些设置和环境会影响他们的行为?

最佳答案

首先,stdin 和 stdout 是大多数语言都有的标准输入和输出流。如果您要通过控制台运行 php,您可以创建如下脚本:

$input = fopen("php://stdin", "r");
$line = trim(fgets($input));

echo $line;

$line = trim(fgets(STDIN));

echo $line;

这些脚本将打开标准控制台输入并允许您输入以回车终止的输入。

现在从命令行 'php://stdout' 和 'php://output' 功能非常相似,假设你没有默认输出缓冲,并且都会给你标准输出到控制台。通过做类似的事情:

$out = fopen("php://stdout", "w");
fwrite($out, "Hello World!");

$out = fopen("php://output", "w");
fwrite($out, "Hello World!");

这两个都会输出 Hello World!按预期发送到控制台。

现在关于输出缓冲,它在 php 配置文件中默认设置为 0(意味着它被禁用)。输出缓冲是一种“阻止”输出的方式,无论它是写入控制台还是浏览器。如果您使用 ob_start 函数打开输出缓冲,则您的任何输出都不会进入控制台/浏览器。相反,它将被放入缓冲区并等待缓冲区达到其最大容量(或直到您手动刷新它),然后它将缓冲区内容转储到标准输出。

开启打印和回显。这些不是真正的函数,它们是语言构造,其中 echo 不返回任何内容,而 print 始终返回 1。两者之间的主要区别在于 echo 可以打印多个由逗号分隔的字符串。

print 和 echo 都打印到输出缓冲区,但由于默认情况下禁用输出缓冲,因此它们似乎直接输出到控制台/浏览器。

现在说说 php://output 和 STDOUT 的区别。如果打开输出缓冲,则只有明显的区别。如果它打开,那么 stdout 输出仍将转到控制台/浏览器的标准输出,但 php://output 将转到缓冲区,直到缓冲区达到其容量或您手动刷新缓冲区。这个例子说明了区别:

<?php
    $out1 = fopen("php://stdout", 'w');
    $out2 = fopen("php://output", "w");
    ob_start();   //enable output buffering
    echo "This is an echo\n";
    print "This is a print\n";
    printf("%d", 52);
    echo "\n";
    fwrite($out1, "Hello World!");
    fwrite($out2, "\nGoodbye World!");
    ob_end_clean(); //turn off output buffering and get rid of it's contents without printing them
?>

请注意如何只有 Hello World!是输出而不是此脚本中的其余输出语句。如果我们注释掉 ob* 语句,那么我们会看到所有其他输出都放在输出缓冲区中。如果我们在脚本末尾使用 ob_end_flush() 而不是 Hello World!然后是输出缓冲区的所有输出,顺序是放入缓冲区的顺序。此外,从这个例子中我们还可以看到 printf 也打印到输出缓冲区(可能使用 echo 或 print 的底层功能)我假设这就是所有其他格式化函数的工作方式但不要引用我的话

就您所指的转义而言,这通常是为了有条件地显示 html 或者当您有一系列不想硬编码的内容时完成的。例如考虑:

<select>
<? foreach($array as $option){ ?>
    <option value="<?=$option?>"><?=$option?></option>
<? }?>
</select>

此代码可用于输出选择的选项数组,无需硬编码值,也无需使用 write echo 或 print 或 print 语句(注意 echo 是通过语法间接使用的)。

令人惊讶的是,此输出也被写入输出缓冲区并包括您在该区域输入的任何空格,但前提是您在控制台(浏览器以不同方式解释空格)。此外,像\n、\t 等转义字符在此上下文中没有任何意义,并且完全按照它们所看到的进行解释。这可以通过将上面的代码修改为:

<?php
$out1 = fopen("php://stdout", 'w');
$out2 = fopen("php://output", "w");
//ob_start();
echo "This is an echo\n";
print "This is a print\n";
printf("%d", 52);
echo "\n";
?>
Jelly Bean
<?php
fwrite($out1, "Hello World!");
fwrite($out2, "\nGoodbye World!");
//ob_end_clean();
?>

如您所见,当输出缓冲语句被注释掉时,会打印 Jelly Bean,但如果您在 Jelly Bean 中重新注释它们,则 Jelly Bean 不会出现在输出中。同样,如果您取消注释 ob* 语句并创建最后一个语句 ob_end_flush(),您将看到从缓冲区输出到标准输出的所有输入,按照输入缓冲区的顺序。

关于php - 在 PHP 中,输出缓冲区打印到哪里?打印什么东西给它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20618777/

相关文章:

php - 不将 php-redbean 的属性保存到数据库

php - 提交后将文本保留在文本字段中

javascript - 在 NodeJs 中将此缓冲区转换为 JSON

python - 将 CPP exe 打印成 Python 脚本输入

php - Apache 服务器日志错误。 AH00126 : Invalid URI in request GET, 等

PHP:将 ID 发送到 HTML 按钮以查看数据库行

将特定数量的字符从一个字符串复制到另一个字符串

python - 使用 sys.stdin 中的先前输入进行提示

c++ - 冒泡排序输出未排序

node.js - 为什么在使用 jest 测试 Node 应用程序时看不到控制台日志输出