18

我正在尝试从 Twitter 获取嵌入推文。所以,我正在使用 cURL 来获取 json。我写了一个小测试,但测试大约需要 5 秒,就像我在本地运行时一样。所以,我不确定我在这里做错了什么。

public function get_tweet_embed($tw_id) {

    $json_url = "https://api.twitter.com/1/statuses/oembed.json?id={$tw_id}&align=left&omit_script=true&hide_media=false";

    $ch = curl_init( $json_url );
    $start_time = microtime(TRUE);
    $JSON = curl_exec($ch);
    $end_time = microtime(TRUE);
    echo $end_time - $start_time; //5.7961111068726

    return $this->get_html($JSON);
}

private function get_html($embed_json) {
    $JSON_Data = json_decode($embed_json,true);
    $tw_embed_code = $JSON_Data["html"];
    return $tw_embed_code;
}

当我粘贴链接并从浏览器测试它时,它真的很快。

4

7 回答 7

28

我曾经有过的最好的加速是重复使用相同的卷曲手柄。替换$ch = curl_init( $json_url );curl_setopt($ch, CURLOPT_URL, $url);。然后外面的功能有一个$ch = curl_init();。您需要$ch在函数中设置全局才能访问它。

重复使用 curl 句柄可以保持与服务器的连接打开。仅当请求之间的服务器相同时,这才有效,就像您的服务器一样。

于 2015-12-24T10:34:18.987 回答
21

加速的最终解决方案是

curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );

问候

于 2014-10-26T01:12:12.337 回答
9

尝试设置 curl_setopt($ch, CURLOPT_ENCODING, '') 它启用gzip压缩

于 2013-10-19T15:57:04.130 回答
7

为了加速 cURL,我建议为 API 创建特殊类(例如ApiClient)并使用一个共享的 cURL 处理程序,只为每个请求更改 URL。还切断名称解析请求并使用压缩响应。

我每天需要从一个 API 服务器处理大约 100 万个实体,这限制了我们只能使用一个并发连接。我创建了那个类。我希望它能帮助其他人优化他们的 curl 请求。

class ApiClient
{
    const CURL_TIMEOUT = 3600;
    const CONNECT_TIMEOUT = 30;
    const HOST = 'api.example.com';
    const API_TOKEN = 'token';

    /** @var resource CURL handler. Reused every time for optimization purposes */
    private $ch;
    /** @var string URL for API. Calculated at creating object for optimization purposes */
    private $url;

    public function __construct()
    {
        $this->url = 'https://' . self::HOST . '/v1/entity/view?token=' . self::API_TOKEN . '&id=';
                                // Micro-optimization: every concat operation takes several milliseconds
                                // But for millions sequential requests it can save a few seconds
        $host = [implode(':', [ // $host stores information for domain names resolving (like /etc/hosts file)
            self::HOST, // Host that will be stored in our "DNS-cache"
            443, // Default port for HTTPS, can be 80 for HTTP
            gethostbyname(self::HOST), // IPv4-address where to point our domain name (Host)
        ])];
        $this->ch = curl_init();
        curl_setopt($this->ch, CURLOPT_ENCODING, '');  // This will use server's gzip (compress data)
                                                       // Depends on server. On some servers can not work
        curl_setopt($this->ch, CURLOPT_RESOLVE, $host); // This will cut all requests for domain name resolving
        curl_setopt($this->ch, CURLOPT_TIMEOUT, self::CURL_TIMEOUT); // To not wait extra time if we know
                                                            // that api-call cannot be longer than CURL_TIMEOUT
        curl_setopt($this->ch, CURLOPT_CONNECTTIMEOUT, self::CONNECT_TIMEOUT); // Close connection if server doesn't response after CONNECT_TIMEOUT
        curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); // To return output in `curl_exec`
    }

    /** @throws \Exception */
    public function requestEntity($id)
    {
        $url = $this->url . $id;

        curl_setopt($this->ch, CURLOPT_URL, $url);

        $data = curl_exec($this->ch);

        if (curl_error($this->ch)) {
            throw new \Exception('cURL error (' . curl_errno($this->ch) . '): ' . curl_error($this->ch));
        }

        return $data;
    }

    public function __destruct()
    {
        curl_close($this->ch);
    }
}

此外,如果您没有限制只能与服务器建立一个连接,则可以使用curl_multi_*函数。

于 2018-11-14T12:59:06.603 回答
6

关于环境,我在 PHP 中观察到 cURL 通常在大多数环境中运行得非常快,除了 CPU 较低且网络性能较慢的地方。例如,在我的 MAMP 安装的 localhost 上,curl 很快,在更大的亚马逊实例上,curl 很快。但是在一个小的蹩脚主机上,我发现它存在性能问题,连接速度明显变慢。虽然,我不确定为什么会更慢。此外,它肯定不会慢 5 秒。

为了帮助确定它是 PHP 还是您的环境,您应该尝试通过命令行与 curl 交互。至少如果 PHP 代码仍然是 5 秒,您将能够排除问题。

于 2013-10-19T18:07:14.990 回答
4

尝试

CURLOPT_TCP_FASTOPEN => 1

... 激活 TCP-Fast-Open。

它被添加到 cURL 7.49.0,被添加到 PHP 7.0.7。

于 2019-09-27T10:32:48.523 回答
2

尝试使用 with--ipv4参数。

这将迫使 curl 仅使用 ipv-4 并忽略 ipv-6,这仍然与某些设备不太兼容并减慢了进程。添加--ipv4到我的 curl 命令中,将成本从 8 秒减少到 4 秒。这比 %50 快。

于 2018-10-18T23:03:38.883 回答