stream_filter_append

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

stream_filter_append将过滤器附加到流

描述

stream_filter_append(
    资源 $stream,
    字符串 $filtername,
    整数 $read_write = ?,
    混合 $params = ?
): 资源

$filtername 添加到附加到 $stream 的过滤器列表中。

参数

stream

目标流。

filtername

过滤器名称。

read_write

默认情况下,stream_filter_append() 将在文件打开以供读取时(即文件模式:r 和/或 +)将过滤器附加到 读取过滤器链。如果文件打开以供写入(即文件模式:wa 和/或 +),过滤器也将附加到 写入过滤器链STREAM_FILTER_READSTREAM_FILTER_WRITE 和/或 STREAM_FILTER_ALL 也可以传递给 read_write 参数以覆盖此行为。

params

此过滤器将使用指定的 $params 添加到列表的末尾,因此在流操作期间将最后调用。若要将过滤器添加到列表的开头,请使用 stream_filter_prepend().

返回值

成功时返回资源,失败时返回 false。该资源可用于在调用 stream_filter_remove() 时引用此过滤器实例。

如果 $stream 不是资源,或者如果找不到 $filtername,则返回 false

示例

示例 #1 控制过滤器应用的位置

<?php
/* 打开一个用于读写的测试文件 */
$fp = fopen('test.txt', 'w+');

/* 将 ROT13 过滤器应用于
* 写入过滤器链,但不应用于
* 读取过滤器链 */
stream_filter_append($fp, "string.rot13", STREAM_FILTER_WRITE);

/* 将一个简单的字符串写入文件
* 它将在
* 输出时进行 ROT13 转换 */
fwrite($fp, "This is a test\n");

/* 返回到文件的开头 */
rewind($fp);

/* 读取文件的原始内容。
* 如果过滤器也应用于
* 读取过滤器链,我们将会看到
* 文本被 ROT13 转换回其原始状态 */
fpassthru($fp);

fclose($fp);

/* 预期输出
---------------

Guvf vf n grfg

*/
?>

备注

注意: 使用自定义(用户)过滤器时
必须首先调用 stream_filter_register() 以将所需的用户过滤器注册到 $filtername

注意: 流数据以块的形式从资源(本地和远程)中读取,任何未消耗的数据都会保留在内部缓冲区中。当一个新的过滤器被附加到流时,内部缓冲区中的数据此时会通过新的过滤器进行处理。这与 stream_filter_prepend() 的行为不同。

注意: 当为读写添加过滤器时,会创建两个过滤器实例。必须对 stream_filter_append() 调用两次,分别使用 STREAM_FILTER_READSTREAM_FILTER_WRITE 来获取两个过滤器资源。

参见

添加备注

用户贡献的备注 5 个备注

7
Dan J
8 年前
请注意,应用于 STDOUT 的流过滤器在通过 echo 或 print 输出时不会被调用。

这可以通过标准 ROT13 过滤器轻松演示
<?php
stream_filter_append
( STDOUT, "string.rot13" );

print
"Hello PHP\n";
// 输出 "Hello PHP"

fprintf( STDOUT, "Hello PHP\n" );
// 输出 "Uryyb CUC"
?>

如果您想过滤 STDOUT,您可能可以使用通过 ob_start 添加的输出缓冲回调获得更好的效果
https://php.net/manual/en/function.ob-start.php

在撰写本文时,有一个关于支持流过滤器 echo 和 print 的 PHP 特性请求
https://bugs.php.net/bug.php?id=30583
7
dlvoy
16 年前
在一次脚本调用期间对大量文件使用压缩过滤器时,我遇到了
致命错误:已用尽 xxx 字节的允许内存大小
即使我的最大内存限制设置非常高(128MB)

解决方法是在使用流完成后使用 stream_filter_remove 记住删除过滤器

<?php
foreach($lot_of_files as $filename)
{
$fp = fopen($filename, 'rb');
$filter_params = array('level' => 2, 'window' => 15, $memory => 6);
$s_filter = stream_filter_append($fp, 'zlib.deflate', STREAM_FILTER_READ, $filter_params);
// 此处的流操作代码

stream_filter_remove($s_filter);

fclose($fp);
}
?>
4
net_navard at yahoo dot com
18 年前
大家好

在过滤器列表中添加流过滤器是先添加还是后添加的区别仅仅在于它们应用于流的顺序。

例如,如果您从文件中读取数据,并且给定的过滤器使用 stream_filter_prepend() 放置在第一个位置,那么数据将首先由该过滤器处理。

此示例读取文件数据,过滤器在读取操作开始时应用

<?php
/* 打开一个测试文件以供读取 */
$fp = fopen("test.txt", "r");
/* 将 ROT13 过滤器应用于
* 读取过滤器链,但不应用于
* 写入过滤器链 */
stream_filter_prepend($fp, "string.rot13",
STREAM_FILTER_READ);
// 读取文件数据
$contents=fread($fp,1024);
// 文件数据首先被过滤并存储在 $contents 中
echo $contents;
fclose($fp);
?>

另一方面,如果使用 stream_filter_append(),则过滤器将在数据操作的末尾应用。 重要的是过滤器应用于流的顺序。 回到示例,从文件数据中删除换行符然后计算字符数与执行逆过程并不相同。 在这种情况下,过滤器应用于流的顺序很重要。

此示例将测试字符串写入文件。 过滤器在写入操作的末尾应用。

<?php
/* 打开一个测试文件以供写入 */
$fp = fopen("test.txt", "w+");
/* 将 ROT13 过滤器应用于
* 写入过滤器链,但不应用于
* 读取过滤器链 */
stream_filter_append($fp, "string.rot13",
STREAM_FILTER_WRITE);
/* 将一个简单的字符串写入文件
* 它将在流操作结束时进行 ROT13 转换
* 输出方式 */
fwrite($fp, "This is a test\n"); // 字符串数据是
首先写入然后进行 ROT13 转换,最后
写入文件
/* 返回到文件的开头 */
rewind($fp);
$contents=fread($fp,512);
fclose($fp);
echo
$contents;
?>

在第一种情况下,数据在写入操作结束时进行转换,而在第二种情况下,数据首先被过滤,然后存储在 $contents 中。

此致
Hossein
1
Sbastien
2 年前
可用的内部过滤器列在 这里

https://php.net/manual/filters.php
0
TingSong
1 年前
解压缩 gzip 流

<?php
$stream
= $s3_client->getReadStream('somefile.csv.gz');
stream_filter_append($stream, 'zlib.inflate', STREAM_FILTER_READ, ['window' => 15+16]);

// 直接读取解压缩的行
$line = fgets($stream);
$columns = str_getcsv($line);

// 处理列中的数据
?>

正如 zlib 文档所述 https://www.zlib.net/manual.html#Advanced

参数 'window' 在 8 到 15 之间指定窗口大小,从 2⁸ 到 2¹⁵ 字节。 可以添加 16 来使用 gzip 头部和尾部包装,而不是 zlib 包装。

此外,window 可以是 -8..-15 用于解包 RAW deflate 数据。
To Top