PHP中的流(streams)浅析_php实例

概述

流(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,这是一种常用的场景。黑客在入侵网站的时候,也可能会用到这部分内容。

时间: 2024-09-15 19:58:09

PHP中的流(streams)浅析_php实例的相关文章

PHP中的流(streams)浅析

  这篇文章主要介绍了PHP中的流(streams)浅析,本文讲解了流的概述.流基础知识.php://包装器.流上下文(Stream Contexts)等内容,需要的朋友可以参考下 概述 流(streams)是PHP4.3版本引入的一个特性,主要是为了统一文件.sockets以及其他类似资源的工作方法.PHP4.3距今已经有很长时间了,但是很多程序员似乎都不能正确使用PHP中的流,当然这也包括我.以前也在一些程序中遇到过流的使用,如php://input,但是一直没机会整理,今天就把这部分知识整

php中stream(流)的用法_php实例

在Java里,流是一个很重要的概念. 流(stream)的概念源于UNIX中管道(pipe)的概念.在UNIX中,管道是一条不间断的字节流,用来实现程序或进程间的通信,或读写外围设备.外部文件等.根据流的方向又可以分为输入流和输出流,同时可以在其外围再套上其它流,比如缓冲流,这样就可以得到更多流处理方法. PHP里的流和Java里的流实际上是同一个概念,只是简单了一点.由于PHP主要用于Web开发,所以"流"这块的概念被提到的较少.如果有Java基础,对于PHP里的流就更容易理解了.其

thinkPHP中create方法与令牌验证实例浅析_php实例

本文实例讲述了thinkPHP中create方法与令牌验证.分享给大家供大家参考,具体如下: thinkPHP的create方法与令牌验证主要是涉及表单的安全性. 代码如下: <?php // 本类由系统自动生成,仅供测试用途 class IndexAction extends Action{ public function index(){ $this->display(); } //一般用户在网站完成信息的添加修改--但是有意外,用户吧网页另存为到本地了,然后在这当中模拟了很多组数据,然后

ThinkPHP中U方法的使用浅析_php实例

thinkPHP中U方法的定义规则如下(方括号内参数根据实际应用决定): U('[项目://][路由@][分组名-模块/]操作? 参数1=值1[&参数N=值N]')或者用数组的方式传入参数:U('[项目://][路由@][分组名-模块/]操作',array('参数1'=>'值1' [,'参数N'=>'值N'])) 如果不定义项目和模块的话 就表示当前项目和模块名称,下面是一些简单的例子: U('Myapp://User/add') // 生成Myapp项目的User模块的add操作的U

PHP中strlen()和mb_strlen()的区别浅析_php实例

在php中常见的计算字符串长度的函数有:strlen和mb_strlen.当字符全是英文字符的时候,两者是一样.这里主要比较一下,中英文混排的时候,两个计算结果. 先来看一个例子: 复制代码 代码如下: <?php  //测试时文件的编码方式要是UTF8  $str='中文a字1符';  echo strlen($str).'<br>';//14  echo mb_strlen($str,'utf8').'<br>';//6  echo mb_strlen($str,'gbk

thinkPHP实现瀑布流的方法_php实例

本文实例讲述了thinkPHP实现瀑布流的方法.分享给大家供大家参考.具体分析如下: 很多人都想做瀑布流的效果,这里告诉大家官网使用的方法,首先要下载瀑布流的插件jquery.masonry.min.js 地址:http://masonry.desandro.com/index.html里面包含的很多示例. 流程: 1. 页面初始化时,调用插件进行一次排版: 2. 当用户将滚动条拖到底部时,用ajax加载一次数据,并排版显示 3. 重复2,直到无数据 Html代码: 复制代码 代码如下: <!D

zend framework中使用memcache的方法_php实例

本文实例讲述了zend framework中使用memcache的方法.分享给大家供大家参考,具体如下: zend framework项目中,以下是具体方法: 1.找到Bootstrap.php添加以下初始化方法(注意:Bootstrap.php是初始化加载所有的操作): protected function _initMemcache() { $frontendOpts = array( 'caching' => true, 'lifetime' => 1800, //缓存生命周期3分钟,根

实例讲解PHP设计模式编程中的简单工厂模式_php实例

简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式.简单工厂模式是由一个工厂对象决定创建出那一种产品类的实例. 1.工厂模式的几种形态工厂模式专门负责将大量有共同接口的类实例化.工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类.工厂模式有以下几种形态: (1)简单工厂(Simple Factory)模式,又称静态工厂方法模式(Static Factory Method Pattern). (2)工厂方法(Factory Meth

Symfony2实现在doctrine中内置数据的方法_php实例

本文实例讲述了Symfony2实现在doctrine中内置数据的方法.分享给大家供大家参考,具体如下: 我们在使用symfony的时候,有时需要在数据库中内置一些数据,那么我们如何在doctrine中设置呢? 所幸,symfony已经为我们封装好了.这里,我们需要用到DoctrineFixturesBundle. 第一步,在composer.json中引入所需的DoctrineFixturesBundle: { "require": { "doctrine/doctrine-