CURLOPT_FILE,curl_multi_exec和fclose [英] CURLOPT_FILE, curl_multi_exec and fclose

查看:206
本文介绍了CURLOPT_FILE,curl_multi_exec和fclose的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建立了一个curl类,可以使用 curl_multi_init 并行下载图片。

I have built a curl class that can download images in parallel using curl_multi_init.

下载功能

public function download(AbstractRequest $request, $f) {

    // Initiate a new curl
    $ch = curl_init();
    // Set curl options
    curl_setopt_array($ch, [
        CURLOPT_URL => $request->getUrl(),
        CURLOPT_FILE => $f,
        CURLOPT_TIMEOUT => 99,
    ]);
    // Add to curl multi handle
    curl_multi_add_handle($this->multiCh, $ch);
}

destructor 该类调用并行请求的执行。

The destructor for the class calls the execution of the parallel requests.

我的问题是,如何从 curl_multi_exec 以便用 fclose()

My question is, how can I get the file resource back from the curl_multi_exec in order to close it with fclose()?

curl会自动关闭我的文件句柄?

Does curl automatically close the file handle for me?

感谢

推荐答案

cURL和PHP都不会自动关闭文件句柄在cURL请求执行后。 PHP将在整个脚本终止时自动关闭它,但如果脚本在cURL请求完成后继续运行一段时间,文件将保持打开状态。

Neither cURL nor PHP automatically close the file handle after the cURL request executes. PHP will close it automatically when the entire script terminates, but if the script continues to run for a while doing other things after the cURL requests complete, the files remain open.

您可以使用一些简单的代码轻松地测试这个数据:

You can easily test this with some simple code:

<?php

error_reporting(E_ALL);
ini_set('display_errors', 1);

// create both cURL resources
$ch1 = curl_init();
$ch2 = curl_init();

// open two temp files for requests
$fp1 = fopen('/tmp/1.txt', 'w+');
$fp2 = fopen('/tmp/2.txt', 'w+');

// set URL and other appropriate options
curl_setopt($ch1, CURLOPT_URL, "http://php.net/");
curl_setopt($ch1, CURLOPT_HEADER, 0);
curl_setopt($ch1, CURLOPT_FILE, $fp1);

curl_setopt($ch2, CURLOPT_URL, "http://lxr.php.net/");
curl_setopt($ch2, CURLOPT_HEADER, 0);
curl_setopt($ch2, CURLOPT_FILE, $fp2);

//create the multiple cURL handle
$mh = curl_multi_init();

//add the two handles
curl_multi_add_handle($mh,$ch1);
curl_multi_add_handle($mh,$ch2);

$active = null;
//execute the handles
echo "Begin requests\n";
do {
    $mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active && $mrc == CURLM_OK) {
    if (curl_multi_select($mh) != -1) {
        do {
            $mrc = curl_multi_exec($mh, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
}

echo "Done\n";

var_dump($fp1, $fp2); // valid resources

echo "Sleep\n";
sleep(10);

//close the handles
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);

fwrite($fp1, "\n\nTEST MORE DATA\n");
fwrite($fp2, "\n\nAND MORE TEST DATA\n");

var_dump($fp1, $fp2); // valid file handles

echo "Last sleep\n";
sleep(10);

// data automatically flushed to disk here
// file handles will be closed by PHP when script terminates here

运行后,您将看到写入这些文件末尾的额外数据,表明句柄在cURL完成后仍然有效。注意:我在PHP 7.0.5和5.6.20上运行这些测试。

After running, you will see the extra data written to the end of those files, showing that the handles were still valid after cURL completed. Note: I ran these tests on PHP 7.0.5 and 5.6.20.

如果你感到冒险,你可以深入到 PHP / cURL来源,然后自己查看。在整个文件中 CURLOPT_FILE 句柄是 ch-> gt; handlers-> write-> fp

If you're feeling adventurous, you can dig into the PHP/cURL source and see for yourself. The CURLOPT_FILE handle is ch->handlers->write->fp throughout the file.

无法获取文件句柄,因此您必须自己跟踪它们。

There is no way to get the file handle back so you'll have to keep track of them yourself.

可以简单地将它们全部添加到数组:

It could be as simple as adding them all to an array:

$fileHandles = array();
//..
$fileHandles[] = $fp1;
$fileHandles[] = $fp2;

然后在 curl_multi_exec 完成时关闭所有:

And then closing them all when curl_multi_exec completes:

foreach($fileHandles as $fp) {
    fclose($fp);
}

但是答案是,它们不会被cURL或PHP自动关闭,直到PHP终止。

But the answer is, they will not be closed automatically by cURL or PHP until PHP terminates.

如果这种情况发生在cURL结束后不久,真的没有必要自己去做。但是,如果这是一个长时间运行的脚本,反复重复多个请求一段时间,它可能不是一个坏主意,跟踪它们,并关闭它们的请求完成。

If this happens very shortly after cURL finishes, there's really no need to do it yourself. But if this is a long running script that repeats multi requests over and over for a long period of time, it might not be a bad idea to keep track of them and close them as the requests finish.

这篇关于CURLOPT_FILE,curl_multi_exec和fclose的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆