分析php://output和php://stdout的区别

PHP包含了以php://开头的一系列输出输出流,如php://stdin, php://stdout等。今天查看代码时,忽然想到一个问题:php://output和php://stdout有什么区别?

从PHP的官方文献中找答案,对输入流php://stdin和php://input的解释分别如下(输出流的解释过于简略):

php://stdin

php://stdin, php://stdout and php://stderr allow direct access to the corresponding input or output stream of the PHP process. The stream references a duplicate file descriptor, so if you open php://stdin and later close it, you close only your copy of the descriptor-the actual stream referenced by STDIN is unaffected. Note that PHP exhibited buggy behavior in this regard until PHP 5.2.1. It is recommended that you simply use the constants STDIN, STDOUT and STDERR instead of manually opening streams using these wrappers.

php://stdin is read-only, whereas php://stdout and php://stderr are write-only.

php://input

php://input is a read-only stream that allows you to read raw data from the request body. In the case of POST requests, it is preferable to use php://input instead of $HTTP_RAW_POST_DATA as it does not depend on special php.ini directives. Moreover, for those cases where $HTTP_RAW_POST_DATA is not populated by default, it is a potentially less memory intensive alternative to activating always_populate_raw_post_data. php://input is not available with enctype=”multipart/form-data”.

文档并未直接阐述两者的区别,仔细对比可得出以下信息:1. 均是只读流; 2. php://stdin是PHP进程的标准输入,php://input用来读取请求正文的原始数据。通过这些信息,该如何正确认识两者的本质区别?

顺着php://stdin进程输入的提示,联想PHP进程的执行过程,再结合SAPI的差异,可以得到两者主要区别:php://stdin是PHP进程的输入流,执行生命周期内均可能有数据流入(例如CLI下的交互式输入);php://input是PHP执行时的外部输入流,一般数据只能读一次(具体看SAPI的实现)。同理可得到php://stdout和php://output的区别:php://stdout是PHP进程的标准输出流,php://output是返回的结果数据流。

下面用代码验证结论:

// file: test.php
file_put_contents("php://output", "message sent by output" . PHP_EOL);
file_put_contents("php://stdout", "message sent by stdout" . PHP_EOL);
print("message sent by print" . PHP_EOL);

echo "SAPI:" , PHP_SAPI , PHP_EOL;

命令行执行文件,输出如下:

message sent by output
message sent by stdout
message sent by print
SAPI:cli

浏览器端请求,输出如下:

message sent by output
message sent by print
SAPI:fpm-fcgi

在命令行下,PHP进程的标准输出流和结果输出流均指向终端,所有消息都打印出来。在浏览器端,PHP进程的输出流被忽略,只有结果数据流被发送到web服务器。同时,print和echo调用的信息都作为执行结果发往结果输出流,所以都正常显示。

最后再感慨一下PHP内置函数的简洁实用,一个file_put_contents函数就搞定流写入操作,换Java需要stream/writer一堆代码,也省去C风格的fopen/fwrite/fclose的繁琐。

(0)

相关推荐

  • 分析php://output和php://stdout的区别

    PHP包含了以php://开头的一系列输出输出流,如php://stdin, php://stdout等.今天查看代码时,忽然想到一个问题:php://output和php://stdout有什么区别? 从PHP的官方文献中找答案,对输入流php://stdin和php://input的解释分别如下(输出流的解释过于简略): php://stdin php://stdin, php://stdout and php://stderr allow direct access to the corr

  • 分析详解python多线程与多进程区别

    目录 1 基础知识 1.1 线程 1.2 进程 1.3 两者的区别 2 Python 多进程 2.1 创建多进程 方法1:直接使用Process 方法2:继承Process来自定义进程类,重写run方法 2.2 多进程通信 Queue Pipe 2.3 进程池 3 Python 多线程 3.1 GIL 3.2 创建多线程 方法1:直接使用threading.Thread() 方法2:继承threading.Thread来自定义线程类,重写run方法 3.3 线程合并 3.4 线程同步与互斥锁 3

  • Java详细分析sleep和wait方法有哪些区别

    目录 一.sleep和wait方法的区别 二.wait方法 wait方法的使用 wait结束等待的条件 三.notify和notifyAll方法 一.sleep和wait方法的区别 根本区别:sleep是Thread类中的方法,不会马上进入运行状态,wait是Object类中的方法,一旦一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该进程 释放同步锁:sleep会释放cpu,但是sleep不会释放同步锁的资源,wait会释放同步锁资源 使用范围: slee

  • 实例分析java中重载与重写的区别

    本文以实例详细分析了Java中重载与重写的区别,感兴趣的朋友可以参考一下. 一.重载(Overloading): (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型. 重载Overloading是一个类中多态性的一种表现. (2)Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义. 调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性. (3) 重载的时候,方

  • 详细分析交换机、路由器、集线器的区别和联系

    最近看到很多人在询问交换机.集线器.路由器是什么,功能如何,有何区别,笔者就这些问题简单的做些解答. 首先说HUB,也就是集线器.它的作用可以简单的理解为将一些机器连接起来组成一个局域网.而交换机(又名交换式集线器)作用与集线器大体相同.但是两者在性能上有区别:集线器采用的式共享带宽的工作方式,而交换机是独享带宽.这样在机器很多或数据量很大时,两者将会有比较明显的.而路由器与以上两者有明显区别,它的作用在于连接不同的网段并且找到网络中数据传输最合适的路径 ,可以说一般情况下个人用户需求不大.路由

  • PHP全局变量与超级全局变量区别分析

    本文分析了PHP全局变量与超级全局变量区别.分享给大家供大家参考,具体如下: 全局变量就是在函数外面定义的变量.不能在函数中直接使用.因为它的作用域不会到函数内部.所以在函数内部使用的时候常常看到类似global $a; 超全局变量作用域在所有脚本都有效.所以,在函数可直接使用.比如 $_GET,$_SERVER都是超全局变量.除$_GET,$_POST,$_SERVER,$_COOKIE等之外的超全局变量保存在$GLOBALS数组中.注意,不要误写成$_GLOBALS.有点受到$_POST的影

  • 分析 Vue 中的 computed 和 watch 的区别

    目录 一.computed介绍 1.1.get 和 set 用法 1.2.计算属性缓存 二.watch介绍 三.两者区别 3.1.对于 computed 3.2.对于 watch 四.应用场景 一.computed介绍 computed 用来监控自己定义的变量,该变量在 data 内没有声明,直接在 computed 里面定义,页面上可直接使用. //基础使用 {{msg}} <input v-model="name" /> //计算属性 computed:{ msg:fu

  • Vue3中emits与attrs的区别分析

    目录 结论 实践分析 扩展 总结 结论 当在父组件自定义事件,若没有在子组件中声明时,将自动绑定在父组件的$attrs上:而当在子组件声明时,则不会在父组件的$attrs上出现 实践分析 为了验证emits和attrs的区别,我们构造这样的组件结构 <div> <com-one-vue/> </div> <div> <com-one-vue/> </div> 其具体的Vue文件及代码为(注意,以下语法均采用 setup语法糖 ): A

  • 图文分析详解计算机网络TCP与UDP两者区别及原理

    目录 1.概念 2.从是否面向连接来看 2.1.UDP 2.2.TCP 3.从连接对象个数来看 3.1.UDP 3.2.TCP 4.从对应用报文的处理来看 4.1.UDP 4.2.TCP 发送方: 接收方: 5.从向其上层提供传输服务来看 5.1.UDP 5.2.TCP 6.从首部格式来看 6.1.UDP 6.2.TCP 7.总结 1.概念 UDP和TCP 在使用TCP/IP 体系结构的网络通信中,这两个协议的使用频率仅次于网际层的IP协议.TCP/IP 体系结构应用层中的某些协议需要使用运输层

  • PHP易混淆函数的区别及用法汇总

    本文实例分析了PHP易混淆函数的区别及用法.分享给大家供大家参考.具体分析如下: 1.echo和print的区别 PHP中echo和print的功能基本相同(输出),但是两者之间还是有细微差别的.echo输出后没有返回值,但print有返回值,当其执行失败时返回flase.因此可以作为一个普通函数来使用,例如执行下面的代码后变量$r的值将为1. PHP代码: 复制代码 代码如下: $r = print "Hello World"; 这意味着print可用在一些复杂的表达式中,而echo

随机推荐