php丢失curl句柄参考

时间:2018-12-04 20:34:55

标签: php curl request php-curl

在代码段的底部,我试图从多手柄上移除卷曲手柄。但是PHP报告它是无效的curl句柄。 curl_close调用报告相同的内容。我很困惑,因为我还没有在此之上关闭它。

我在任何地方都丢了它。我看不到哪里...

    foreach ($urls as $url) {

        $request = [];
        $request['url'] = $url;
        $request['body'] = '';
        $request['response_headers'] = [];
        $request['curl_handle'] = curl_init();

        $url['config'] = json_decode($url['config'], true);

        if($url['config']['method'] == 'GET') {
            curl_setopt($request['curl_handle'], CURLOPT_HTTPGET, true);
        }

        curl_setopt($request['curl_handle'], CURLOPT_URL, $url['source_url']);

        curl_setopt($request['curl_handle'], CURLOPT_WRITEFUNCTION, function($curl, $body) use (&$request) {
            $request['body'] .= $body;
            return strlen($body);
        });
        curl_setopt($request['curl_handle'], CURLOPT_HEADERFUNCTION, function($curl, $header) use (&$request) {
            $request['response_headers'][] = $header;
            return strlen($header);
        });

        $followRedirects = boolval($url['config']['follow_redirects']);
        curl_setopt($request['curl_handle'], CURLOPT_FOLLOWLOCATION, $followRedirects);  

        curl_setopt($request['curl_handle'], CURLOPT_CONNECTTIMEOUT, 10);  
        curl_setopt($request['curl_handle'], CURLOPT_TIMEOUT, 120);

        curl_setopt($request['curl_handle'], CURLOPT_MAXREDIRS, intval($url['config']['total_redirects']));

        curl_setopt($request['curl_handle'], CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);

        curl_setopt($request['curl_handle'], CURLOPT_MAXFILESIZE, intval($url['config']['max_download']));

        curl_setopt($request['curl_handle'], CURLOPT_SSL_VERIFYHOST, false);  
        curl_setopt($request['curl_handle'], CURLOPT_SSL_VERIFYPEER, false);  

        $requests[] = &$request;
    }

    $mh = curl_multi_init();

    //add the handles
    foreach ($requests as &$request) {
        curl_multi_add_handle($mh, $request['curl_handle']);
    }

    $active = null;
    //execute the handles
    do {
        $mrc = curl_multi_exec($mh, $active);
        print('after exec');
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);

    while ($active && $mrc == CURLM_OK) {            
        $mrc = curl_multi_exec($mh, $active);

        if (curl_multi_select($mh) != -1) {
            do {
                $mrc = curl_multi_exec($mh, $active);
                print('performing again');
            } while ($mrc == CURLM_CALL_MULTI_PERFORM);
        }
    }

    if ($mrc != CURLM_OK) {
        print("Curl multi read error $mrc\n");
    }

    foreach ($requests as &$request) {
        processResponse($request);

        curl_multi_remove_handle($mh, $request['curl_handle']);
        curl_close($request['curl_handle']);
    }

    curl_multi_close($mh);

2 个答案:

答案 0 :(得分:0)

可能您需要更改以下几行:

foreach ($requests as &$request) {
        processResponse($request);

        curl_multi_remove_handle($mh, $request['curl_handle']);
        curl_close($request['curl_handle']);
    }

     foreach ($requests as &$request) {
            processResponse($request);

            curl_close($request['curl_handle']);
            curl_multi_remove_handle($mh, $request['curl_handle']);

        }

答案 1 :(得分:0)

问题在于$ request是通过引用复制到$ requests中的,因此同一curl_handle会通过多次curl传递,然后多次传递给close_handle。该修复程序未将$ request通过引用设置为$ requests。

我改变了:

$requests[] = &$request;

$requests[] = $request;

那解决了我的问题。