PHP中的流(streams)浅析


Posted in PHP onJuly 02, 2015

概述

流(streams)是PHP4.3版本引入的一个特性,主要是为了统一文件、sockets以及其他类似资源的工作方法。PHP4.3距今已经有很长时间了,但是很多程序员似乎都不能正确使用PHP中的流,当然这也包括我。以前也在一些程序中遇到过流的使用,如php://input,但是一直没机会整理,今天就把这部分知识整理下。

流是由PHP提供的资源,可以供我们透明的使用,而且流是一个非常强大的工具。适当的在程序中使用流,可以将我们的程序带到一个新的高度。

PHP手册中对流的描述如下:

Streams were introduced with PHP 4.3.0 as a way of generalizing file, network, data compression, and other operations which share a common set of functions and uses. In its simplest definition, a stream is a resource object which exhibits streamable behavior. That is, it can be read from or written to in a linear fashion, and may be able to fseek() to an arbitrary locations within the stream.

每一种流都实现了一个包装器(wrapper),包装器包含一些额外的代码用来处理特殊的协议和编码。PHP提供了一些内置的包装器,我们也可以很轻松的创建和注册自定义的包装器。我们甚至可以使用上下文(contexts)和过滤器来改变和增强包装器。

流基础知识

PHP中流的形式如:<scheme>://<target>。<scheme>是包装器的名字,<target>的内容取决于不同的包装器语法。
默认的包装器是file://,也就是说每次我们访问文件系统的时候都使用了流。例如,我们可以使用如下两种方式来读取文件:readfile('/path/to/somefile.txt')和readfile('file:///path/to/somefile.txt'),使用这两种方式读取文件,可以得到相同的结果。

正如前面所说,PHP提供了一些内置的包装器、协议和过滤器。查看我们的机器上安装了哪些包装器,可以使用如下几个函数:

<?php

    var_dump(stream_get_transports());

    var_dump(stream_get_wrappers());

    var_dump(stream_get_filters());

?>

我本地的环境输出内容如下:

array (size=8)

  0 => string 'tcp' (length=3)

  1 => string 'udp' (length=3)

  2 => string 'unix' (length=4)

  3 => string 'udg' (length=3)

  4 => string 'ssl' (length=3)

  5 => string 'sslv3' (length=5)

  6 => string 'sslv2' (length=5)

  7 => string 'tls' (length=3)

array (size=12)

  0 => string 'https' (length=5)

  1 => string 'ftps' (length=4)

  2 => string 'compress.zlib' (length=13)

  3 => string 'compress.bzip2' (length=14)

  4 => string 'php' (length=3)

  5 => string 'file' (length=4)

  6 => string 'glob' (length=4)

  7 => string 'data' (length=4)

  8 => string 'http' (length=4)

  9 => string 'ftp' (length=3)

  10 => string 'phar' (length=4)

  11 => string 'zip' (length=3)

array (size=12)

  0 => string 'zlib.*' (length=6)

  1 => string 'bzip2.*' (length=7)

  2 => string 'convert.iconv.*' (length=15)

  3 => string 'string.rot13' (length=12)

  4 => string 'string.toupper' (length=14)

  5 => string 'string.tolower' (length=14)

  6 => string 'string.strip_tags' (length=17)

  7 => string 'convert.*' (length=9)

  8 => string 'consumed' (length=8)

  9 => string 'dechunk' (length=7)

  10 => string 'mcrypt.*' (length=8)

  11 => string 'mdecrypt.*' (length=10)

另外,我们可以自定义或者使用第三方的流。

php://包装器

PHP有它自己的访问输入/输出(I/O)流的包装器。PHP有基本的php://stdin,php://stdout,php://stderr包装器对应默认的I/O资源。还有一个php://input流,它是一个只读的流,流内容是post请求的数据。当我们将数据放在一个post请求的body体内用来请求一个远程服务的时候,这个流特别好用。

因为php://input是最常用到的流,所以这里列出一些知识点:

1.php://input可以读取没有处理过的POST数据。相较于$HTTP_RAW_POST_DATA而言,它给内存带来的压力较小,并且不需要特殊的php.ini设置。php://input不能用于enctype=multipart/form-data

2.仅当Content-Type为application/x-www-form-urlencoded且提交方法是POST方法时,$_POST数据与php://input数据才是”一致”(打上引号,表示它们格式不一致,内容一致)的。其它情况,它们都不一致

3.php://input读取不到GET数据。是因为_GET数据作为query_path写在http请求头部(header)的PATH字段,而不是写在http请求的body部分。

流上下文(Stream Contexts)

这部分内容在编程中几乎没有遇到过,本人研究起来也比较吃力,大家感兴趣的话可以自行百度。

总结

流在平时的编程中用到的并不是很多,在使用xml-rpc的时候,server端获取client数据,主要是通过php输入流input,这是一种常用的场景。黑客在入侵网站的时候,也可能会用到这部分内容。

PHP 相关文章推荐
基于mysql的论坛(3)
Oct 09 PHP
php操作excel文件 基于phpexcel
Jul 02 PHP
PHP系列学习之日期函数使用介绍
Aug 18 PHP
php检测网页是否被百度收录的函数代码
Oct 09 PHP
php+mysql不用递归实现的无限级分类实例(非递归)
Jul 08 PHP
phpmailer发送邮件之后,返回收件人是否阅读了邮件的方法
Jul 19 PHP
PHP字符串word末字符实现大小写互换的方法
Nov 10 PHP
PHP批量查询WordPress留言者E-mail地址实现方法
Feb 15 PHP
tp5框架内使用tp3.2分页的方法分析
May 05 PHP
Laravel5.4框架中视图共享数据的方法详解
Sep 05 PHP
使用PHP+Redis实现延迟任务,实现自动取消订单功能
Nov 21 PHP
php使用fputcsv实现大数据的导出操作详解
Feb 27 PHP
PHP curl使用实例
Jul 02 #PHP
PHP中使用curl入门教程
Jul 02 #PHP
Smarty最简单实现列表奇偶变色的方法
Jul 01 #PHP
PHP中的常见魔术方法功能作用及用法实例
Jul 01 #PHP
PHP获取文件夹大小函数用法实例
Jul 01 #PHP
Thinkphp模板标签if和eq的区别和比较实例分析
Jul 01 #PHP
ThinkPHP V2.2说明文档没有说明的那些事实例小结
Jul 01 #PHP
You might like
php的socket编程详解
2016/11/20 PHP
PHP实现的文件上传类与用法详解
2017/07/05 PHP
a标签的css样式四个状态
2021/03/09 HTML / CSS
AutoSave/自动存储功能实现
2007/03/24 Javascript
JavaScript子类用Object.getPrototypeOf去调用父类方法解析
2013/12/05 Javascript
javascript带回调函数的异步脚本载入方法实例分析
2015/07/02 Javascript
JS取模、取商及取整运算方法示例
2016/10/13 Javascript
浅谈Node.js:Buffer模块
2016/12/05 Javascript
微信小程序实现登录页云层漂浮的动画效果
2017/05/05 Javascript
vue-cli 2.*中导入公共less文件的方法步骤
2018/11/22 Javascript
ES6 Generator函数的应用实例分析
2019/06/26 Javascript
微信小程序引入Vant组件库过程解析
2019/08/06 Javascript
Vue使用mixin分发组件的可复用功能
2019/09/01 Javascript
jQuery Datatables 动态列+跨列合并实现代码
2020/01/30 jQuery
node.js使用net模块创建服务器和客户端示例【基于TCP协议】
2020/02/14 Javascript
vue css 引入asstes中的图片无法显示的四种解决方法
2020/03/16 Javascript
python海龟绘图实例教程
2014/07/24 Python
Python的Flask框架中web表单的教程
2015/04/20 Python
python Spyder界面无法打开的解决方法
2018/04/27 Python
python实现的生成word文档功能示例
2019/08/23 Python
Python3操作Excel文件(读写)的简单实例
2019/09/02 Python
Python SELENIUM上传文件或图片实现过程
2019/10/28 Python
python抓取多种类型的页面方法实例
2019/11/20 Python
Pytorch保存模型用于测试和用于继续训练的区别详解
2020/01/10 Python
如何基于Python代码实现高精度免费OCR工具
2020/06/18 Python
前后端结合实现amazeUI分页效果
2020/08/21 HTML / CSS
美国彩妆品牌:Coastal Scents
2017/04/01 全球购物
贝玲妃英国官网:Benefit英国
2018/02/03 全球购物
中国高端家电购物商城:顺电
2018/03/04 全球购物
加拿大在线旅游公司:Flighthub
2019/03/11 全球购物
幼儿园老师寄语
2014/04/03 职场文书
2014审计局领导班子民主生活会对照检查材料思想汇报
2014/09/20 职场文书
2016高中社会实践心得体会范文
2016/01/14 职场文书
Keras多线程机制与flask多线程冲突的解决方案
2021/05/28 Python
python之django路由和视图案例教程
2021/07/26 Python
浅谈css实现背景颜色半透明的两种方法
2021/12/06 HTML / CSS