PHP的日志流过滤器?

时间:2012-03-06 11:27:49

标签: php sockets

我需要调试我的PHP前端对另一台主机上的后端服务进行的套接字连接,我需要将尽可能接近金属。我已经在各个级别抽象了连接,其中包括让我能够轻松地将stream filters连接到连接。因此问题应该很容易解决:将流过滤器打包到一个类中,该类允许在发送或接收数据时执行任意回调,然后将这些回调附加到几个日志文件中。

唯一的麻烦是我的(天真?)期望应该有一些这样的过滤器实现在线浮动似乎是错误的!我不介意自己编写过滤器,但也许有一些我可以找不到的东西?

作为参考,我在“php logging stream filter”上做了很多明显的变化。

更新:为了澄清一点,我正在寻找的东西可以让我编写与道德相当的代码:

$params = array(
    'onDataSent' => function($data) { echo "Sent: $data\n"; },
    'onDataReceived' => function($data) { echo "Received: $data\n"; },
);

stream_filter_register('logging', 'HookableStreamFilter');
stream_filter_append($someStream, 'logging', STREAM_FILTER_ALL, $params);

1 个答案:

答案 0 :(得分:1)

对于后人来说,这就是我鞭打的结局。过滤器本身来自php_user_filterstream_filter_register的文档中对此进行了描述:

class HookableFilter extends php_user_filter {
    public function filter($in, $out, &$consumed, $closing) {
        $data = '';

        while ($bucket = stream_bucket_make_writeable($in)) {
            $consumed += $bucket->datalen;
            $data .= $bucket->data;
            stream_bucket_append($out, $bucket);
        }

        call_user_func($this->params, $data);
        return PSFS_PASS_ON;
    }
}

请注意,我直接使用$this->params作为回调,这使得它在功能上非常简洁(这是有原因的;见下文)。

使用PHP注册过滤器:

stream_filter_register('generic.hookable', 'HookableFilter');

将过滤器附加到流:

$callback = function($data) { /* log the data */ };
stream_filter_append($stream, 'generic.hookable', STREAM_FILTER_READ, $callback);
stream_filter_append($stream, 'generic.hookable', STREAM_FILTER_WRITE, $callback);

重要说明:据我所见,如果您将过滤器附加到双工流的两个通道(例如,使用stream_socket_client生成的那个),则没有过滤器在调用时通知哪个通道正在运行的方式。因此,如果您需要像我一样区分传入和传出数据,唯一的选择是将过滤器分别连接到每个通道。如果你这样做,你肯定也希望为每个频道提供不同的回调(与上面简化示例中的回调不同)。