php 丢失卷曲句柄参考

php lost curl handle reference

在代码片段的底部,我试图从多手柄中删除卷曲手柄。但是 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);

可能您需要更改以下行:

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']);

        }

问题是 $request 通过引用被复制到 $requests 中,所以同一个 curl_handle 通过 multi curl 传递,然后多次传递到 close_handle。修复不是通过引用将 $request 设置为 $requests。

我改了:

$requests[] = &$request;

$requests[] = $request;

这解决了我的问题。