【问题标题】:Using fread to send chunks of large data使用 fread 发送大数据块
【发布时间】:2018-06-23 04:02:23
【问题描述】:

这是我上一个帖子 (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) 技巧,它仍然重复同样的事情。有什么想法吗?

【问题讨论】:

    标签: php fwrite fread


    【解决方案1】:

    在为此工作了大约 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 在标头中仍将其读取为 > 250MB。
    • 当我设法让这段代码工作时,它会在某些块上超时,这是因为 Cloudflare 在 100 秒内需要一个 HTTP 标头,否则它会超时。谢天谢地,我的脚本将通过 CRON 执行,因此不需要通过 Cloudflare 即可工作。但是,如果您希望在浏览器中执行代码,那么您可能想看看这个。 https://github.com/marcialpaulg/Fixing-Cloudflare-Error-524

    【讨论】:

    • 我看到了 $fp 和 $handle。它们都应该是 $fp 吗?
    猜你喜欢
    • 2019-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-19
    相关资源
    最近更新 更多