使用 fread 发送大数据块

Using fread to send chunks of large data

这是我之前主题 (PHP CURL Chunked encoding a large file (700mb)) 的延续,但我现在即兴创作了一些其他内容。

现在,我正在尝试使用 fread,然后通过 CURL 逐块发送文件(每个块大约 1MB),虽然这个想法很好并且确实有效。它确实使服务器超时,所以我想知道是否有任何方法可以减少它每秒发送一个块的次数,或者有什么方法可以让它不会完全超载我的 PHP 进程。

$length             = (1024 * 1024) * 1;
$handle             = fopen($getFile, "r");

while (($buffer = fread($handle, $length)) !== false) {
    if ($response = sendChunk($getServer, $buffer)) {
        $chunk++;
        print "Chunk " . $chunk . " Sent (Code: " . $response . ")! \n";
    }
}

函数sendChunk

function sendChunk($url, $chunk) {
    $POST_DATA = [
        'file'  =>      base64_encode($chunk)
    ];

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_TIMEOUT, 2048);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $POST_DATA);
    curl_exec($curl);
    $response = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    curl_close ($curl);
    return $response;
}

我尝试制作它以便您可以逐行读取文件,但它不起作用,因为视频文件(mp4、wmv)有很多随机字符,什么不是。

更新: 我发现了这个问题,超时实际上是 CloudFlare 在没有此类 HTTP 响应时超时的结果。所以我决定 运行 使用 SSH 的脚本并且它工作正常....除了一件事。

文件成功发送后,它将继续在此无限循环中发送 0 字节的块,我被告知这是因为 feof() 在测量时并不总是准确的。所以我尝试使用 ($buffer = fread($handle, $length) !== false) 技巧,它仍然重复同样的事情。有什么想法吗?

在为此工作了大约 8 小时后,我注意到我没有使用 $buffer 来发送块,所以现在我已经这样做了。

while (!feof($fp) && ($buffer = fread($handle, $length)) !== false) {
    if ($response = sendChunk($getServer, $buffer)) {
        $chunk++;
        print "Chunk " . $chunk . " Sent (Code: " . $response . ")! \n";
    }
}

一切正常,我做了一些其他的修改,比如检查 200 的响应代码。但它的核心是有效的。

对于正在使用 Cloudflare 并希望将文件(最大 2GB)传输到另一台服务器并希望通过 CURL 使用它的任何人的一课。

  • 在我看来,有比仅使用 CURL 更好的方法,但客户要求通过这种方式完成,但它有效。
  • Cloudflare 对免费用户的最大上传限制为 250MB,您不能通过 CURL 支持的流功能进行分块上传,因为 Cloudflare 在 header.
  • 中仍将其读取为 > 250MB
  • 当我设法让这段代码工作时,它会在某些块上超时,这是因为 Cloudflare 在 100 秒内需要 HTTP header 或超时。值得庆幸的是,我的脚本将通过 CRON 执行,因此它不需要通过 Cloudflare 来工作。但是,如果您希望在浏览器中执行代码,那么您可能想看看这个。 https://github.com/marcialpaulg/Fixing-Cloudflare-Error-524