在 PHP 中,流(stream)是一种非常强大的抽象概念,用于统一处理文件、网络、内存等各种数据源和目标。当我们操作流时,理解其过滤器和元数据非常重要。本文将介绍如何用 stream_get_filters() 和 stream_get_meta_data() 结合使用,以获取流的详细信息。
stream_get_filters() 是一个 PHP 内置函数,用于列出当前可用的所有流过滤器。流过滤器可以用来修改流中的数据,比如压缩、加密、编码转换等。
<?php
$filters = stream_get_filters();
print_r($filters);
?>
运行这个代码,你可能会看到类似这样的输出:
Array
(
[0] => string.rot13
[1] => string.toupper
[2] => zlib.inflate
[3] => zlib.deflate
...
)
这告诉我们当前 PHP 配置中支持的过滤器。
stream_get_meta_data() 用于获取一个已打开流的元信息。它返回一个包含各种细节的关联数组,比如:
流是否可读、可写
是否到达文件末尾(eof)
封装协议(比如 http、file)
是否阻塞
超时设置
示例:
<?php
$fp = fopen('http://gitbox.net/', 'r');
$meta = stream_get_meta_data($fp);
print_r($meta);
fclose($fp);
?>
输出类似:
Array
(
[wrapper_type] => http
[stream_type] => tcp_socket/ssl
[mode] => r
[unread_bytes] => 0
[seekable] =>
[timed_out] =>
[blocked] => 1
[eof] =>
)
我们可以把两者结合起来,先获取支持的过滤器,再打开一个流,查看它的元信息,并尝试给它附加过滤器。
示例代码:
<?php
// 列出当前可用的过滤器
$filters = stream_get_filters();
echo "可用过滤器列表:\n";
foreach ($filters as $filter) {
echo "- $filter\n";
}
// 打开一个 HTTP 流
$url = 'http://gitbox.net/';
$fp = fopen($url, 'r');
if (!$fp) {
die("无法打开 $url\n");
}
// 查看流的元数据
$meta = stream_get_meta_data($fp);
echo "\n流的元信息:\n";
print_r($meta);
// 尝试附加一个过滤器(如果支持 zlib.inflate)
if (in_array('zlib.inflate', $filters)) {
stream_filter_append($fp, 'zlib.inflate', STREAM_FILTER_READ);
echo "已附加 zlib.inflate 过滤器到流。\n";
} else {
echo "zlib.inflate 过滤器不可用。\n";
}
fclose($fp);
?>
不是所有流都支持所有过滤器,比如 http 流可能不支持 zlib.inflate,需要根据上下文判断。
使用 stream_filter_append() 前最好用 stream_get_filters() 检查过滤器是否存在。
stream_get_meta_data() 每次调用只返回当下状态,流状态可能随着读取或写入而变化。