高级PHP:为cURL句柄配置onBefore和/或onAfter回调?

时间:2011-06-10 20:51:16

标签: php events http curl

我正在使用PHP中的cURL实现,并利用curl_multi_init()和curl_multi_exec()来并行执行批量请求。我已经做了一段时间了,并理解了这一部分。

但是,请求正文包含使用时间戳计算的签名。从生成此签名的那一刻起,我就有一个有限的时间窗口来发出请求,然后服务器会在请求完成后拒绝该请求。大多数时候这很好。但是,在某些情况下,我需要进行大量上传(5 GB以上)。

如果我将请求批处理到100,200,1000,20000或其中任何一个池中,并且我将大量数据上载到服务器,则执行的初始请求将成功完成。但是,在签名中的时间戳到期之后,以后的请求才会开始,因此服务器会拒绝这些请求。

我正在使用的当前流程是这样的:

  1. 提前进行任何处理。
  2. 将尚未执行的cURL句柄添加到批处理中。
  3. 让cURL处理执行所有请求。
  4. 查看回来的数据并解析所有数据。
  5. 我有兴趣找到一种方法来执行一个回调函数,该函数可以按需生成签名,并在PHP / cURL执行该特定请求时更新请求体。我知道你可以将一个回调函数绑定到一个cURL句柄,该句柄将在请求发生时重复执行,并且你可以在整个过程中访问cURL句柄。

    所以我的问题是:有没有办法为cURL句柄配置onBefore和/或onAfter回调?可以在cURL执行请求之前立即执行的操作,然后在响应返回后立即执行的操作,以便可以解析响应数据。

    我想做更多面向事件的事情,如下:

    1. 向批处理中添加一个尚未执行的cURL句柄,指定一个回调函数,在cURL(不是我自己)执行请求时(前后都执行)执行。
    2. 获取批处理请求的结果,并根据数据执行任何操作。

3 个答案:

答案 0 :(得分:1)

不,使用cURL的内置功能是不可能的。但是,在本机函数周围实现包装以实现您想要的功能是微不足道的。

例如,模糊地实施观察者模式:

<?php

class CurlWrapper {
    private $ch;
    private $listeners;

    public function __construct($url) {
        $this->ch = curl_init($url);
        $this->setopt(CURLOPT_RETURNTRANSFER, true);
    }

    public function setopt($opt, $value) {
        $this->notify('setopt', array('option' => $opt, 'value' => $value));
        curl_setopt($this->ch, $opt, $value);
    }

    public function setopt_array($opts) {
        $this->notify('setopt_array', array('options' => $opts));
        curl_setopt_array($this->ch, $opts);
    }

    public function exec() {
        $this->notify('beforeExec', array());
        $ret = curl_exec($this->ch);
        $this->notify('afterExec', array('result' => $ret));
        return $ret;
    }

    public function attachListener($event, $fn) {
        if (is_callable($fn)) {
            $this->listeners[$event][] = $fn;
        }
    }

    private function notify($event, $data) {
        if (isset($this->listeners[$event])) {
            foreach ($this->listeners[$event] as $listener) {
                $listener($this, $data);
            }
        }
    }
}

$c = new CurlWrapper('http://stackoverflow.com');
$c->setopt(CURLOPT_HTTPGET, true);
$c->attachListener('beforeExec', function($handle, $data) {
    echo "before exec\n";
});

$result = $c->exec();
echo strlen($result), "\n";

您可以使用addListener向对象添加事件侦听器(必须是callables),并在相关时刻自动调用它们。

显然你需要做更多工作才能使它符合你的要求,但我认为这不是一个糟糕的开始。

答案 1 :(得分:0)

与cURL有关的不是高级PHP。这是“先进的捣蛋”。

如果您通过cURL获得了大量数据,我建议不要使用cURL(实际上,我总是建议不要使用cURL)

我会研究一个套接字实现。好的不容易找到,但不难写自己。

答案 2 :(得分:0)