在回调php中捕获http请求

时间:2012-07-01 11:29:27

标签: php http

我正在尝试捕获回调函数中出现的http请求:

// Code omitted
public function capture($fn)
{
  // start http capture
  $fn();
  // end http capture and stores the capture in a variable
}


//example usage
$request->capture(function(){
  do_some_http_request_with_curl_or_whatever_you_want();
});

我用ob_start()和php包装器尝试过各种各样的东西......但没有任何作用,非常感谢帮助!

2 个答案:

答案 0 :(得分:0)

它不可能捕获任何任意HTTP请求,因为回调有很多可能的方法来解决它:

  • 包含网址包装的高级功能(例如file_get_contents
  • 更多低级方法(例如流,套接字)
  • 自定义PHP扩展(例如curl)

这些方法中的每一种都有(或者都有!)不同的方式允许你挂钩请求的机制,所以除非你想要的所有机制支持挂钩< em>和回调主动与你合作,没有办法做到这一点。

答案 1 :(得分:0)

如果您只需要支持流包装器(即不使用套接字函数),则应该可以取消注册http流包装器并添加您自己的包装器,然后转发它们。这是一个例子:

<?php

class HttpCaptureStream
{
    private $fd;
    public static $captured;

    public static function reset()
    {
        static::$captured = array();
    }

    public function stream_open($path, $mode, $options, &$opened_path)
    {
        static::$captured[] = $path;

        $this->fd = $this->restored(function () use ($path, $mode) {
            return fopen($path, $mode);
        });

        return (bool) $this->fd;
    }

    public function stream_read($count)
    {
        return fread($this->fd, $count);
    }

    public function stream_write($data)
    {
        return fwrite($this->fd, $data);
    }

    public function stream_tell()
    {
        return ftell($this->fd);
    }

    public function stream_eof()
    {
        return feof($this->fd);
    }

    public function stream_seek($offset, $whence)
    {
        return fseek($this->fd, $offset, $whence);
    }

    public function stream_stat()
    {
        return fstat($this->fd);
    }

    protected function restored($f)
    {
        stream_wrapper_restore('http');

        $result = $f();

        stream_wrapper_unregister('http');
        stream_wrapper_register('http', __CLASS__);

        return $result;
    }
}

function capture($f) {
    stream_wrapper_unregister('http');

    stream_wrapper_register('http', 'HttpCaptureStream');
    HttpCaptureStream::reset();

    $f();

    stream_wrapper_restore('http');
}

capture(function () {
    file_get_contents('http://google.com');
    file_get_contents('http://stackoverflow.com');

    var_dump(HttpCaptureStream::$captured);
});