在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()每次調用只返回當下狀態,流狀態可能隨著讀取或寫入而變化。