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


Posted in PHP onMay 06, 2018

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的繁琐。

PHP 相关文章推荐
Mysql的GROUP_CONCAT()函数使用方法
Mar 28 PHP
用PHP读取超大文件的实例代码
Apr 01 PHP
PHP中数组的三种排序方法分享
May 07 PHP
php常用Stream函数集介绍
Jun 24 PHP
在PHP中运行Linux命令并启动SSH服务的例子
Jun 12 PHP
Windows下的PHP 5.3.x安装 Zend Guard Loader教程
Sep 06 PHP
php 5.6版本中编写一个PHP扩展的简单示例
Jan 20 PHP
php批量删除cookie的简单实现方法
Jan 26 PHP
PHP中使用curl伪造IP的简单方法
Aug 07 PHP
php给图片添加文字水印方法汇总
Aug 27 PHP
三个思路解决laravel上传文件报错:413 Request Entity Too Large问题
Nov 13 PHP
PHP使用非对称加密算法RSA
Apr 21 PHP
PHP 布尔值的自增与自减的实现方法
May 03 #PHP
PHPExcel 修改已存在Excel的方法
May 03 #PHP
PHP中PDO事务处理操作示例
May 02 #PHP
PHP简单实现解析xml为数组的方法
May 02 #PHP
PHP实现动态压缩js与css文件的方法
May 02 #PHP
Yii2框架数据验证操作实例详解
May 02 #PHP
Yii2框架类自动加载机制实例分析
May 02 #PHP
You might like
全国FM电台频率大全 - 4 山西省
2020/03/11 无线电
咖啡语言
2021/03/03 咖啡文化
用PHP和ACCESS写聊天室(七)
2006/10/09 PHP
php中对xml读取的相关函数的介绍一
2008/06/05 PHP
php feof用来识别文件末尾字符的方法
2010/08/01 PHP
php生成N个不重复的随机数实例
2013/11/12 PHP
PHP 无限级分类
2017/05/04 PHP
php实现生成PDF文件的方法示例【基于FPDF类库】
2018/07/21 PHP
php pdo连接数据库操作示例
2019/11/18 PHP
用JavaScript仿PS里的羽化效果代码
2011/12/20 Javascript
javascript中节点的最近的相关节点访问方法
2013/03/20 Javascript
jQuery中对节点进行操作的相关介绍
2013/04/16 Javascript
不要使用jQuery触发原生事件的方法
2014/03/03 Javascript
js代码实现的加入收藏效果并兼容主流浏览器
2014/06/23 Javascript
2014年50个程序员最适用的免费JQuery插件
2014/12/15 Javascript
PHP实现的各种中文编码转换类分享
2015/01/23 Javascript
jquery实现一个简单的表单验证实例
2016/03/30 Javascript
JS实现点击网页判断是否安装app并打开否则跳转app store
2016/11/18 Javascript
详解jQuery lazyload 懒加载
2016/12/19 Javascript
jquery操作select取值赋值与设置选中实例
2017/02/28 Javascript
jQuery extend()详解及简单实例
2017/05/06 jQuery
JavaScript之面向对象_动力节点Java学院整理
2017/06/29 Javascript
详解Webpack + ES6 最新环境搭建与配置
2018/06/04 Javascript
基于bootstrap页面渲染的问题解决方法
2018/08/09 Javascript
vue+koa2实现session、token登陆状态验证的示例
2019/08/30 Javascript
Vue scoped及deep使用方法解析
2020/08/01 Javascript
python xpath获取页面注释的方法
2019/01/14 Python
python2.7 安装pip的方法步骤(管用)
2019/05/05 Python
python中的split、rsplit、splitlines用法说明
2020/10/23 Python
anaconda升级sklearn版本的实现方法
2021/02/22 Python
使用tkinter实现三子棋游戏
2021/02/25 Python
加拿大花店:1800Flowers.ca
2016/11/16 全球购物
世界上最大的隐形眼镜商店:1-800 Contacts
2018/11/03 全球购物
公司财务自我评价分享
2013/12/17 职场文书
教师自我反思材料
2014/02/14 职场文书
2015年乡镇扶贫工作总结
2015/04/08 职场文书