PHP支持的协议和封装协议

2024-01-09 44

PHP 带有很多内置 URL 风格的封装协议,可用于类似 fopen()、 copy()、 file_exists() 和 filesize() 的文件系统函数。 除了这些封装协议,还能通过 stream_wrapper_register() 来注册自定义的封装协议。

注意:用于描述一个封装协议的 URL 语法仅支持 scheme://… 的语法。 scheme:/ 和 scheme: 语法是不支持的。

一、file://

file:// — 访问本地文件系统。文件系统 是 PHP 使用的默认封装协议,展现了本地文件系统。 当指定了一个相对路径(不以/、\、\\或 Windows 盘符开头的路径)提供的路径将基于当前的工作目录,在很多情况下是脚本所在的目录,除非被修改了,使用 CLI 的时候,目录默认是脚本被调用时所在的目录。

在某些函数里,例如 fopen() 和 file_get_contents(), include_path 会可选地搜索,也作为相对的路径。

用法:

  • /path/to/file.ext
  • relative/path/to/file.ext
  • fileInCwd.ext
  • C:/path/to/winfile.ext
  • C:\path\to\winfile.ext
  • \\smbserver\share\path\to\winfile.ext
  • file:///path/to/file.ext

二、http://

http:// — https:// — 访问 HTTP(s) 网址

允许通过 HTTP 对文件/资源进行可读访问。默认使用 HTTP 1.0 GET。 HTTP 请求会附带一个 Host: 头,用于兼容基于域名的虚拟主机。 如果在你的 php.ini 文件中或字节流上下文(context)配置了 user_agent 字符串,它也会被包含在请求之中。

  • 数据流允许读取资源的 body,而 headers 则储存在了 $http_response_header 变量里。如果需要知道文档资源来自哪个 URL(经过所有重定向的处理后), 需要处理数据流返回的系列响应报头(response headers)。
  • The from directive will be used for the From: header if set and not overwritten by the 上下文(Context)选项和参数。

用法:

  • http://example.com
  • http://example.com/file.php?var1=val1&var2=val2
  • http://user:password@example.com
  • https://example.com
  • https://example.com/file.php?var1=val1&var2=val2
  • https://user:password@example.com

三、ftp://

ftp:// — ftps:// — 访问 FTP(s) URLs

允许通过 FTP 读取存在的文件,以及创建新文件。 如果服务器不支持被动(passive)模式的 FTP,连接会失败。

打开文件后你既可以读也可以写,但是不能同时进行。 当远程文件已经存在于 ftp 服务器上,如果尝试打开并写入文件的时候, 未指定上下文(context)选项 overwrite,连接会失败。 如果要通过 FTP 覆盖存在的文件, 指定上下文(context)的 overwrite 选项来打开、写入。 另外可使用 FTP 扩展来代替。

如果设置了 php.ini 中的 from 指令, 这个值会作为匿名(anonymous)ftp 的密码。

用法:

  • ftp://example.com/pub/file.txt
  • ftp://user:password@example.com/pub/file.txt
  • ftps://example.com/pub/file.txt
  • ftps://user:password@example.com/pub/file.txt

四、php://

php:// — 访问各个输入/输出流(I/O streams)。PHP 提供了一些杂项输入/输出(IO)流,允许访问 PHP 的输入输出流、标准输入输出和错误描述符, 内存中、磁盘备份的临时文件流以及可以操作其他读取写入文件资源的过滤器。

1、php://stdin, php://stdout 和 php://stderr

php://stdin、php://stdout 和 php://stderr 允许直接访问 PHP 进程相应的输入或者输出流。 数据流引用了复制的文件描述符,所以如果你打开 php://stdin 并在之后关了它, 仅是关闭了复制品,真正被引用的 STDIN 并不受影响。 推荐你简单使用常量 STDIN、 STDOUT 和 STDERR 来代替手工打开这些封装器。

php://stdin 是只读的, php://stdout 和 php://stderr 是只写的。

2、php://input

php://input 是个可以访问请求的原始数据的只读流。 如果启用了 enable_post_data_reading 选项, php://input 在使用 enctype=”multipart/form-data” 的 POST 请求中不可用。

3、php://output

php://output 是一个只写的数据流, 允许你以 print 和 echo 一样的方式 写入到输出缓冲区。

4、php://fd

php://fd 允许直接访问指定的文件描述符。 例如 php://fd/3 引用了文件描述符 3。

5、php://memory 和 php://temp

php://memory 和 php://temp 是一个类似文件 包装器的数据流,允许读写临时数据。 两者的一个区别是 php://memory 总是把数据储存在内存中, 而 php://temp 会在内存量达到预定义的限制后(默认是 2MB)存入临时文件中。 临时文件位置的决定和 sys_get_temp_dir() 的方式一致。

php://temp 的内存限制可通过添加 /maxmemory:NN 来控制,NN 是以字节为单位、保留在内存的最大数据量,超过则使用临时文件。

某些 PHP 扩展可能需要标准 IO 流,并且可能尝试将指定流转换为标准 IO 流。对于内存流,此转换可能会失败,因为需要 C fopencookie() 函数可以调用。此 C 函数在 Windows 上无效。

6、php://filter

php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 这对于一体式(all-in-one)的文件函数非常有用,类似 readfile()、 file() 和 file_get_contents(), 在数据流内容读取之前没有机会应用其他过滤器。

php://filter 目标使用以下的参数作为它路径的一部分。 复合过滤链能够在一个路径上指定。详细使用这些参数可以参考具体范例。

php://filter 参数:

  • resource=<要过滤的数据流>:指定了你要筛选过滤的数据流。
  • read=<读链的筛选列表>:可以设定一个或多个过滤器名称,以管道符(|)分隔。
  • write=<写链的筛选列表>:可以设定一个或多个过滤器名称,以管道符(|)分隔。
  • <;两个链的筛选列表>:任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。

php://temp/maxmemory示例:

这个可选选项允许设置 php://temp 开始使用临时文件前的最大内存限制。

<?php
// 限制内存为 5 MB。
$fiveMBs = 5 * 1024 * 1024;
$fp = fopen("php://temp/maxmemory:$fiveMBs", 'r+');
fputs($fp, "hello\n");
// 读取刚才写入的内容。
rewind($fp);
echo stream_get_contents($fp);
?>

php://filter/resource=<待过滤的数据流>示例:

这个参数必须位于 php://filter 的末尾,并且指向需要过滤筛选的数据流。

<?php
/* 这简单等同于:
readfile("http://www.example.com");
实际上没有指定过滤器 */
readfile("php://filter/resource=http://www.example.com");
?>

php://filter/read=<读链需要应用的过滤器列表>示例:

这个参数采用一个或以管道符 | 分隔的多个过滤器名称。

<?php
/* 这会以大写字母输出 www.example.com 的全部内容 */
readfile("php://filter/read=string.toupper/resource=http://www.example.com");
/* 这会和以上所做的一样,但还会用 ROT13 加密。 */
readfile("php://filter/read=string.toupper|string.rot13/resource=http://www.example.com");
?>

php://filter/write=<写链需要应用的过滤器列表>示例:

这个参数采用一个或以管道符 | 分隔的多个过滤器名称。

<?php
/* 这会通过 rot13 过滤器筛选出字符 "Hello World"
然后写入当前目录下的 example.txt */
file_put_contents("php://filter/write=string.rot13/resource=example.txt","Hello World");
?>

php://memory 和 php://temp 示例:

php://memory 和 php://temp 是一次性的,比如:stream 流关闭后,就无法再次得到以前的内容了。

file_put_contents('php://memory', 'PHP');
echo file_get_contents('php://memory'); // 啥也没有

五、zlib://

  • zlib:// — bzip2:// — zip:// — 压缩流
  • compress.zlib:// and compress.bzip2://
  • zlib: 的功能类似 gzopen(),但是 其数据流还能被 fread() 和其他文件系统函数使用。 不建议使用,因为会和其他带“:”字符的文件名混淆; 请使用 compress.zlib:// 替代。
  • compress.zlib://、 compress.bzip2:// 和 gzopen()、bzopen() 是相等的。并且可以在不支持 fopencookie 的系统中使用。

ZIP 扩展 注册了 zip: 封装器。 自 PHP 7.2.0 和 libzip 1.2.0+ 起,加密归档开始支持密码,允许数据流中使用密码。 字节流上下文(stream contexts)中使用 ‘password’ 选项设置密码。

用法:

  • compress.zlib://file.gz
  • compress.bzip2://file.bz2
  • zip://archive.zip#dir/file.txt

六、data://

  • data:// — 数据(RFC 2397)
  • data:(» RFC 2397)数据流封装器。

用法:

  • data://text/plain;base64,

七、glob://

  • glob:// — 查找匹配的文件路径模式
  • glob: 数据流包装器。

用法:

  • glob://

八、phar://

  • phar:// — PHP 归档
  • phar:// 数据流包装器。

用法:

  • phar://

九、ssh2://

  • ssh2:// — 安全外壳协议 2
  • ssh2.shell:// ssh2.exec:// ssh2.tunnel:// ssh2.sftp:// ssh2.scp:// (PECL)

注意:该封装器默认没有激活。

为了使用 ssh2.*:// 封装协议,必须从 » PECL 中安装有效的 » SSH2 扩展。除了支持传统的 URI 登录信息,ssh2 封装协议也支持通过 URL 的主机(host)部分来复用打开连接。

用法:

  • ssh2.shell://user:pass@example.com:22/xterm
  • ssh2.exec://user:pass@example.com:22/usr/local/bin/somecmd
  • ssh2.tunnel://user:pass@example.com:22/192.168.0.1:14
  • ssh2.sftp://user:pass@example.com:22/path/to/filename

十、rar://

rar:// — RAR。封装协议采用 url 编码,(相对/绝对)路径的 RAR 归档、一个可选的星号(*)、一个可选的井号(# )和一个可选的存储在归档中的 url 编码条目名称。指定条目名称必须带有井号,条目名称开头的斜线是可选的。该封装协议可以打开文件和目录。当打开目录时,星号会强制返回未编码的目录条目名称。如果不指定星号,将返回 URL 编码的目录条目名称 —— 这样做的原因是存在类似 URL 编码的文件名时,允许封装协议能够与内置方法(比如 RecursiveDirectoryIterator)一起正确使用。自 PECL rar 3.0.0 起可用。

如果不包含井号和条目名称部分,将会显示归档的根目录。与常规目录不同的是生成的流不会包含诸如修改时间之类的信息, 因为根目录不会存储在归档的条目中。当访问根目录时, RecursiveDirectoryIterator 与封装协议一起使用时需要在 ULR 中包含井号,以便正确构建子级 URL。

注意:该封装协议不会默认启用

为了使用 rar:// 封装协议,必须从 » PECL 中安装有效的 » rar 扩展。

用法:

  • rar://<url encoded archive name>[*][#[<url encoded entry name>]]

示例:

遍历 RAR 归档:

<?php
class MyRecDirIt extends RecursiveDirectoryIterator {
function current() {
return rawurldecode($this->getSubPathName()) .
(is_dir(parent::current())?" [DIR]":"");
}
}
$f = "rar://" . rawurlencode(dirname(__FILE__)) .
DIRECTORY_SEPARATOR . 'dirs_and_extra_headers.rar#';
$it = new RecursiveTreeIterator(new MyRecDirIt($f));
foreach ($it as $s) {
echo $s, "\n";
}
?>

以上示例的输出类似于:

|-allow_everyone_ni [DIR]
|-file1.txt
|-file2_אּ.txt
|-with_streams.txt
\-אּ [DIR]
|-אּ\%2Fempty%2E [DIR]
| \-אּ\%2Fempty%2E\file7.txt
|-אּ\empty [DIR]
|-אּ\file3.txt
|-אּ\file4_אּ.txt
\-אּ\אּ_2 [DIR]
|-אּ\אּ_2\file5.txt
\-אּ\אּ_2\file6_אּ.txt

打开加密文件(报头加密):

<?php
$stream = fopen("rar://" .
rawurlencode(dirname(__FILE__)) . DIRECTORY_SEPARATOR .
'encrypted_headers.rar' . '#encfile1.txt', "r", false,
stream_context_create(
array(
'rar' =>
array(
'open_password' => 'samplepassword'
)
)
)
);
var_dump(stream_get_contents($stream));
/* 在 WinRAR 中创建日期和最后访问日期是可选的,
* 因此大多数文件都没有 */
var_dump(fstat($stream));
?>

以上示例的输出类似于:

string(26) "Encrypted file 1 contents."
Array
(
[0] => 0
[1] => 0
[2] => 33206
[3] => 1
[4] => 0
[5] => 0
[6] => 0
[7] => 26
[8] => 0
[9] => 1259550052
[10] => 0
[11] => -1
[12] => -1
[dev] => 0
[ino] => 0
[mode] => 33206
[nlink] => 1
[uid] => 0
[gid] => 0
[rdev] => 0
[size] => 26
[atime] => 0
[mtime] => 1259550052
[ctime] => 0
[blksize] => -1
[blocks] => -1
)

十一、ogg://

ogg:// — 音频流。通过包装器 ogg:// 读取的文件, 是作为 OGG/Vorbis 格式的压缩音频编码。 同样,通过包装器 ogg:// 写入或追加的数据格式也是压缩音频。 当 stream_get_meta_data() 用于一个打开读取的 OGG/Vorbis 文件时,会返回关于数据流的详细信息,包含了 vendor 标签、任何内含的 comments、 channels 数字、采样率(rate),以及 用 bitrate_lower、bitrate_upper、 bitrate_nominal 和 bitrate_window 描述的可变比特率范围。

ogg:// (PECL)

注意:该封装器默认未激活。

要使用 ogg:// 封装协议,必须从 » PECL 中安装有效的 » OGG/Vorbis 扩展。

用法:

  • ogg://soundfile.ogg
  • ogg:///path/to/soundfile.ogg
  • ogg://http://www.example.com/path/to/soundstream.ogg

十二、expect://

expect:// — 处理交互式的流。由 expect:// 封装协议打开的数据流 PTY 通过提供了对进程 stdio、stdout 和 stderr 的访问。

注意:该封装协议默认未开启。

为了使用 expect:// 封装协议,必须从 » PECL 中安装有效的 » Expect 扩展。

expect:// (PECL)

用法:

  • expect://command
  • 广告合作

  • QQ群号:707632017

温馨提示:
1、本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。邮箱:2942802716#qq.com(#改为@)。 2、本站原创内容未经允许不得转裁,转载请注明出处“站长百科”和原文地址。