PHP的Streams以及包装器wrapper如何使用
今天给大家来说一下讲述了PHP流Streams、包装器wrapper概念与用法。总结给大家看一下。
我们知道,流Streams这个概念是在php4.3引进的,是对流式数据的抽象,用于统一数据操作,比如文件数据、网络数据、压缩数据等,以使可以共享同一套函数,php的文件系统函数就是这样的共享,比如file_get_contents()函数即可打开本地文件也可以访问url就是这一体现。简单点讲,流就是表现出流式数据行为的资源对象。
以线性方式进行读写,并可以在流里面任意位置进行搜索。
流有点类似数据库抽象层,在数据库抽象层方面,不管使用何种数据库,在抽象层之上都使用相同的方式操作数据,而流是对数据的抽象,它不管是本地文件还是远程文件还是压缩文件等等,只要来的是流式数据,那么操作方式就是一样的。
有了流这个概念就引申出了包装器wrapper这个概念,每个流都对应一种包装器,流是从统一操作这个角度产生的一个概念,而包装器呢是从理解流数据内容出发产生的一个概念,也就是这个统一的操作方式怎么操作或配置不同的内容;
这些内容都是以流的方式呈现,但内容规则是不一样的,比如http协议传来的数据是流的方式,但只有http包装器才理解http协议传来的数据的意思,可以这么理解,流就是一根流水的管子,只不过它流出的是数据,包装器就是套在流这根管子外层的一个解释者,它理解流出的数据的意思,并能操作它。
官方手册说:“一个包装器是告诉流怎么处理特殊协议或编码的附加代码”明白这句话的意思了吗?
包装器可以嵌套,一个流外面包裹了一个包装器后,还可以在外层继续包裹包装器,这个时候里层的包装器相对于外层的包装器充当流的角色
在php自身底层实现的c语言开发文档有这样的解释:
流API操作一对不同级别:在基本级别,api定义了php_stream对象表示流式数据源,在稍微高一点的级别,api定义了php_stream_wrapper对象。
它包裹低一级别的php_stream对象,以提供取回URL的内容和元数据、添加上下文参数的能力,调整包装器行为;
每一种流打开后都可以应用任意数量的过滤器在上面,流数据会经过过滤器的处理,笔者认为过滤器这个词用得有点不准确,有些误导人。
从字面意思看好像是去掉一些数据的感觉,应该称为数据调整器,因为它既可去掉一些数据,也可以添加,还可以修改,但历史原因约定俗成,也就称为过滤器了,大家心里明白就好。
我们经常看到下面的词,来解释下他们的区别:
资源和数据:资源是比较宏观的说法,通常包含数据,而数据是比较具象的说法,在开发程序的时候经常说是数据,而在软件规划时说是资源,他们是近义词,就像软件设计和程序开发的区别一样。
上下文和参数:上下文是比较宏观的说法,经常用在沟通上面,具体点讲就是一次沟通本身的参数,而参数这个说法往往用在比较具体的事情上面,比如说函数
上面解释了概念性的东西,下面来看看具体内容:
php支持的协议和包装器请看这里:http://php.net/manual/zh/wrappers.php:
(笔者注:原标题是:支持的协议和封装协议,中文翻译有点误导,准确的讲就是支持的协议和包装器,从英文版面就很清楚)
默认的支持了一些协议和包装器,请用stream_get_wrappers()函数查看.也可以自定义一个包装器,用stream_wrapper_register()注册
尽管RFC 3986里面可以使用:做分割符,但php只允许://,所以url请使用"scheme://target"这样的格式
file:// — 访问本地文件系统,在用文件系统函数时默认就使用该包装器 http:// — 访问 HTTP(s) 网址 ftp:// — 访问 FTP(s) URLs php:// — 访问各个输入/输出流(I/O streams) zlib:// — 压缩流 data:// — 数据(RFC 2397) glob:// — 查找匹配的文件路径模式 phar:// — PHP 归档 ssh2:// — Secure Shell 2 rar:// — RAR ogg:// — 音频流 expect:// — 处理交互式的流
如何实现一个自定义的包装器:
在用fopen、fwrite、fread、fgets、feof、rewind、file_put_contents、file_get_contents等等文件系统函数操作流时,数据是先传给定义的包装器类对象,包装器再去操作流。
如何实现一个自定义的流包装器呢?php提供了一个类原型,只是原型而已,不是接口也不是类,不能用于继承:
streamWrapper { /* 属性 */ public resource $context ; /* 方法 */ __construct ( void ) __destruct ( void ) public bool dir_closedir ( void ) public bool dir_opendir ( string $path , int $options ) public string dir_readdir ( void ) public bool dir_rewinddir ( void ) public bool mkdir ( string $path , int $mode , int $options ) public bool rename ( string $path_from , string $path_to ) public bool rmdir ( string $path , int $options ) public resource stream_cast ( int $cast_as ) public void stream_close ( void ) public bool stream_eof ( void ) public bool stream_flush ( void ) public bool stream_lock ( int $operation ) public bool stream_metadata ( string $path , int $option , mixed $value ) public bool stream_open ( string $path , string $mode , int $options , string &$opened_path ) public string stream_read ( int $count ) public bool stream_seek ( int $offset , int $whence = SEEK_SET ) public bool stream_set_option ( int $option , int $arg1 , int $arg2 ) public array stream_stat ( void ) public int stream_tell ( void ) public bool stream_truncate ( int $new_size ) public int stream_write ( string $data ) public bool unlink ( string $path ) public array url_stat ( string $path , int $flags ) }
在这个原型里面定义的方法,根据自己需要去定义,并不要求全部实现,这就是为什么不定义成接口的原因,因为有些实现根本用不着某些方法,
这带来很多灵活性,比如包装器是不支持删除目录rmdir功能的,那么就不需要实现streamWrapper::rmdir
由于未实现它,如果用户在包装器上调用rmdir将有错误抛出,要自定义这个错误那么也可以实现它并在其内部抛出错误
streamWrapper也不是一个预定义类,测试class_exists("streamWrapper")就知道,它只是一个指导开发者的原型
官方手册提供了一个例子:http://php.net/manual/zh/stream.streamwrapper.example-1.php
本博客提供一个从drupal8系统中抽取修改过的包装器例子,请看drupal8源码分析关于流那一部分
流系列函数,官方手册:http://php.net/manual/zh/ref.stream.php
常用的函数如下:
stream_bucket_append函数:为队列添加数据 stream_bucket_make_writeable函数:从操作的队列中返回一个数据对象 stream_bucket_new函数:为当前队列创建一个新的数据 stream_bucket_prepend函数:预备数据到队列 stream_context_create函数:创建数据流上下文 stream_context_get_default函数:获取默认的数据流上下文 stream_context_get_options函数:获取数据流的设置 stream_context_set_option函数:对数据流、数据包或者上下文进行设置 stream_context_set_params函数:为数据流、数据包或者上下文设置参数 stream_copy_to_stream函数:在数据流之间进行复制操作 stream_filter_append函数:为数据流添加过滤器 stream_filter_prepend函数:为数据流预备添加过滤器 stream_filter_register函数:注册一个数据流的过滤器并作为PHP类执行 stream_filter_remove函数:从一个数据流中移除过滤器 stream_get_contents函数:读取数据流中的剩余数据到字符串 stream_get_filters函数:返回已经注册的数据流过滤器列表 stream_get_line函数:按照给定的定界符从数据流资源中获取行 stream_get_meta_data函数:从封装协议文件指针中获取报头/元数据 stream_get_transports函数:返回注册的Socket传输列表 stream_get_wrappers函数:返回注册的数据流列表 stream_register_wrapper函数:注册一个用PHP类实现的URL封装协议 stream_select函数:接收数据流数组并等待它们状态的改变 stream_set_blocking函数:将一个数据流设置为堵塞或者非堵塞状态 stream_set_timeout函数:对数据流进行超时设置 stream_set_write_buffer函数:为数据流设置缓冲区 stream_socket_accept函数:接受由函数stream_ socket_server()创建的Socket连接 stream_socket_client函数:打开网络或者UNIX主机的Socket连接 stream_socket_enable_crypto函数:为一个已经连接的Socket打开或者关闭数据加密 stream_socket_get_name函数:获取本地或者网络Socket的名称 stream_socket_pair函数:创建两个无区别的Socket数据流连接 stream_socket_recvfrom函数:从Socket获取数据,不管其连接与否 stream_socket_sendto函数:向Socket发送数据,不管其连接与否 stream_socket_server函数:创建一个网络或者UNIX Socket服务端 stream_wrapper_restore函数:恢复一个事先注销的数据包 stream_wrapper_unregister函数:注销一个URL地址包
相信看了这些案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
相关阅读:
以上是PHP的Streams以及包装器wrapper如何使用的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题











PHP 8.4 带来了多项新功能、安全性改进和性能改进,同时弃用和删除了大量功能。 本指南介绍了如何在 Ubuntu、Debian 或其衍生版本上安装 PHP 8.4 或升级到 PHP 8.4

如果您是一位经验丰富的 PHP 开发人员,您可能会感觉您已经在那里并且已经完成了。您已经开发了大量的应用程序,调试了数百万行代码,并调整了一堆脚本来实现操作

Visual Studio Code,也称为 VS Code,是一个免费的源代码编辑器 - 或集成开发环境 (IDE) - 可用于所有主要操作系统。 VS Code 拥有针对多种编程语言的大量扩展,可以轻松编写

JWT是一种基于JSON的开放标准,用于在各方之间安全地传输信息,主要用于身份验证和信息交换。1.JWT由Header、Payload和Signature三部分组成。2.JWT的工作原理包括生成JWT、验证JWT和解析Payload三个步骤。3.在PHP中使用JWT进行身份验证时,可以生成和验证JWT,并在高级用法中包含用户角色和权限信息。4.常见错误包括签名验证失败、令牌过期和Payload过大,调试技巧包括使用调试工具和日志记录。5.性能优化和最佳实践包括使用合适的签名算法、合理设置有效期、

本教程演示了如何使用PHP有效地处理XML文档。 XML(可扩展的标记语言)是一种用于人类可读性和机器解析的多功能文本标记语言。它通常用于数据存储

字符串是由字符组成的序列,包括字母、数字和符号。本教程将学习如何使用不同的方法在PHP中计算给定字符串中元音的数量。英语中的元音是a、e、i、o、u,它们可以是大写或小写。 什么是元音? 元音是代表特定语音的字母字符。英语中共有五个元音,包括大写和小写: a, e, i, o, u 示例 1 输入:字符串 = "Tutorialspoint" 输出:6 解释 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。总共有 6 个元

静态绑定(static::)在PHP中实现晚期静态绑定(LSB),允许在静态上下文中引用调用类而非定义类。1)解析过程在运行时进行,2)在继承关系中向上查找调用类,3)可能带来性能开销。

PHP的魔法方法有哪些?PHP的魔法方法包括:1.\_\_construct,用于初始化对象;2.\_\_destruct,用于清理资源;3.\_\_call,处理不存在的方法调用;4.\_\_get,实现动态属性访问;5.\_\_set,实现动态属性设置。这些方法在特定情况下自动调用,提升代码的灵活性和效率。
