在PHP中重定向I/O.

Evi*_*Elf 2 php

<?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
?>
Run Code Online (Sandbox Code Playgroud)

为什么重定向到新STDOUT隐式工作,但是新STDIN的重定向必须明确地发生?

Bas*_*ers 5

原始的STDIN,STDOUT和STDERR是PHP中的系统常量.它们在PHP初始化时填充了标准输入,输出和错误的文件描述符资源.

php.net文档描述了有关常量资源的以下内容:

常数的值; 只允许标量和空值.标量值是整数,浮点数,字符串或布尔值.可以定义资源常量,但不建议这样做,并且可能导致不可预测的行为.

fclose(STDOUT)被调用时,文件描述符资源被关闭,并从STDOUT不断脱落.与常量的默认行为相反,STDOUT常量会发生变化.

当字符串被回显时echo "Hello, World!",PHP将不使用STDOUT常量,但它将从操作系统实时查询当前的"标准输出"文件描述符.而且,STDOUT常量本身一旦被fclose'd就会变得无法使用.即使如下语句fwrite(STDOUT, "hello")无法正常工作.

为标准输出配置新的文件描述符时,可以方便地输入新的文件描述符$STDOUT.请注意,这是一个变量而不是常量.根据定义,不可能在PHP中重新定义常量,系统常量STDOUT在这里也不例外.目前无法将新文件描述符重新分配给STDOUT常量.

最后,为了使这项工作更直观,PHP团队应该考虑使用便利函数来重新分配这些文件描述符,或者至少使系统常量更像"魔术常量",因为它们会自动评估实际的文件描述符.