欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PHP-自定义流过滤器

程序员文章站 2022-04-08 21:39:28
...

最近在看《Modern PHP》,发现以前没有用过流过滤器,学习记录一下。

桶:总所周知(好吧,我才知道),PHP流会把数据分成按次序排列的桶,一个桶中城防的数据流量是固定的(如4096字节)。流过滤器一次能接受一个或多个桶。一定时间内过滤器接收到的桶叫做桶队列。

PS:每个桶对象都有两个公开属性:datadatalen.分别是桶内容和内容长度。

<?php 

/**
* 脏词过滤器
* 1.自定义过滤器必须扩展内置的php_user_filter类
* 2.实现filter()方法
* 3.在stream_filter_register()函数注册自己的过滤器
*/
class DirtyWordsFilter extends php_user_filter
{
    /**
     * 该方法内实现过滤
     * @param  resource   $in        流来的桶队列
     * @param  resource   $out       流走的桶队列
     * @param  int        &$consumed 处理的字节数
     * @param  bool       $closing   是否是最后一个桶队列
     */
    public function filter($in, $out, &$consumed, $closing)
    {
        $words = array('grime', 'grease', 'dirt', 'fuck');//脏词,可配置到文件中。
        $wordData = array();

        foreach ($words as $word) {
            $replacement = array_fill(0, mb_strlen($word), '*');
            $wordData[$word] = implode('', $replacement);//将脏词跟和谐符号(*)以键值对存放
        }

        $bad = array_keys($wordData);
        $good = array_values($wordData);

        /**
         * (PHP 5)
         * stream_bucket_make_writeable — Return a bucket object from the brigade for operating on
         * 
         * (PHP 5, PHP 7)
         * stream_bucket_append — Append bucket to brigade
         * 
         * PSFS_PASS_ON Filter processed successfully with data available in the out bucket brigade.
         */

        while ($bucket = stream_bucket_make_writeable($in)) {//迭代每个桶
            $bucket->data = str_replace($bad, $good, $bucket->data);//替换
            $consumed += $bucket->datalen;//增加已经处理的数据量
            stream_bucket_append($out, $bucket);//将该桶对象放入流向下游的队列
        }

        return PSFS_PASS_ON;
    }
}
stream_filter_register('dirty_words_filter', 'DirtyWordsFilter');//注册流过滤器
//测试环节
$handle = fopen('data.txt', 'rb');
stream_filter_append($handle, 'dirty_words_filter');

while (feof($handle) !== true) {
    echo fgets($handle);
}
fclose($handle);
//data.txt: 'Hi, you grime,haha grease dirt, this is a fuck'
//输出:'Hi, you *****,haha ****** ****, this is a ****'
相关标签: