我需要调试我的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);
答案 0 :(得分:1)
对于后人来说,这就是我鞭打的结局。过滤器本身来自php_user_filter
,stream_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
生成的那个),则没有过滤器在调用时通知哪个通道正在运行的方式。因此,如果您需要像我一样区分传入和传出数据,唯一的选择是将过滤器分别连接到每个通道。如果你这样做,你肯定也希望为每个频道提供不同的回调(与上面简化示例中的回调不同)。