使用 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
这是我之前主题 (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