Guzzle 6 大文件上传/分块
Guzzle 6 Large file uploads / Chunking
我读过,如果 Guzzle 无法确定 Content-Length,它将发送 Transfer-Encoding:Chunked headers 和 back-end 上的 cURL 将处理分块。但我显然达到了 post_max_size 限制。 (POST Content-Length of 524288375 bytes exceeds the limit of 8388608 bytes)当 POSTing 到工作的 uploadChunkerController 时。我知道上传处理程序(端点)适用于较小的文件。我觉得我我的 Guzzle 选项配置有误。我必须将 verify
设置为 false
,并且我需要 post 和 api_key
请求。
$client = new Client();
$fh = fopen('../storage/random-500M.pdf', 'r');
$url = 'https://local:8443/app_dev.php/_uploader/bigupload/upload';
$request = $client->request(
'POST',
$url,
[
'verify' => false,
'multipart' => [
[
'name' => 'api_key',
'contents' => 'abc123'
],
[
'name' => 'file',
'contents' => $fh,
'filename' => 'bigupload.pdf'
]
]
]
);
编辑php.ini 设置既不是一种选择,也不是解决方案。我发现很多 'solutions' 似乎适用于旧版本的 Guzzle。我是不是想太多了?有更简单的解决方案吗?
分块传输编码在这种情况下没有帮助。
它用于通过分段发送(和生成)内容来尽快提供内容。它与大小限制无关(如您的情况)。
你唯一的办法就是增加服务器的限制。
在深入研究 Guzzle 和 cURL 源代码后,他们没有 'automatic' 发送 'chunks' 的方式。 Headers 未设置,他们无法分割正在发送的文件。我使用 Guzzle 与原始 PHP cURL 调用想出了自己的解决方案。
/**
* @Route("/chunks", name="chunks")
*/
public function sendFileAction()
{
$jar = new \GuzzleHttp\Cookie\SessionCookieJar('SESSION_STORAGE', true);
$handler = new CurlHandler();
$stack = HandlerStack::create($handler);
$client = new Client(['cookies'=>true, 'handler' => $stack]);
$filename = 'files/huge-1gig-file.jpg';
$filesize = filesize($filename);
$fh = fopen($filename, 'r');
$chunkSize = 1024 * 2000;
$boundary = '----iCEBrkUploaderBoundary' . uniqid();
$url = 'https://localhost/app_dev.php/_uploader/bigupload/upload';
rewind($fh); // probably not necessary
while (! feof($fh)) {
$pos = ftell($fh);
$chunk = fread($fh, $chunkSize);
$calc = $pos + strlen($chunk)-1;
// Not sure if this is needed.
//if (ftell($fh) > $chunkSize) {
// $pos++;
//}
$request = $client->request(
'POST',
$url,
[
'cookies' => $jar,
'debug' => false,
'verify' => false,
'headers' => [
'Transfer-Encoding' => 'chunked',
'Accept-Encoding' => 'gzip, deflate, br',
'Accept' => 'application/json, text/javascript, */*; q=0.01',
'Connection' => 'keep-alive',
'Content-disposition' => 'attachment; filename="' . basename($filename) . '"',
'Content-length' => $calc - $pos,
'Content-Range' => 'bytes ' . $pos . '-' . $calc . '/' . $filesize
],
'multipart' => [
[
'name' => 'api_key,
'contents' => 'aaabbbcc-deff-ffed-dddd-1234567890123'
],
[
'name' => 'file',
'contents' => $chunk,
'filename' => basename($filename),
'headers' => [
'Content-Type' => 'multipart/form-data; boundary=' . $boundary
]
]
]
]
);
}
return new Response('ok', 200);
}
我希望这对其他人有所帮助。 Comments/Suggestions 欢迎。
我读过,如果 Guzzle 无法确定 Content-Length,它将发送 Transfer-Encoding:Chunked headers 和 back-end 上的 cURL 将处理分块。但我显然达到了 post_max_size 限制。 (POST Content-Length of 524288375 bytes exceeds the limit of 8388608 bytes)当 POSTing 到工作的 uploadChunkerController 时。我知道上传处理程序(端点)适用于较小的文件。我觉得我我的 Guzzle 选项配置有误。我必须将 verify
设置为 false
,并且我需要 post 和 api_key
请求。
$client = new Client();
$fh = fopen('../storage/random-500M.pdf', 'r');
$url = 'https://local:8443/app_dev.php/_uploader/bigupload/upload';
$request = $client->request(
'POST',
$url,
[
'verify' => false,
'multipart' => [
[
'name' => 'api_key',
'contents' => 'abc123'
],
[
'name' => 'file',
'contents' => $fh,
'filename' => 'bigupload.pdf'
]
]
]
);
编辑php.ini 设置既不是一种选择,也不是解决方案。我发现很多 'solutions' 似乎适用于旧版本的 Guzzle。我是不是想太多了?有更简单的解决方案吗?
分块传输编码在这种情况下没有帮助。
它用于通过分段发送(和生成)内容来尽快提供内容。它与大小限制无关(如您的情况)。
你唯一的办法就是增加服务器的限制。
在深入研究 Guzzle 和 cURL 源代码后,他们没有 'automatic' 发送 'chunks' 的方式。 Headers 未设置,他们无法分割正在发送的文件。我使用 Guzzle 与原始 PHP cURL 调用想出了自己的解决方案。
/**
* @Route("/chunks", name="chunks")
*/
public function sendFileAction()
{
$jar = new \GuzzleHttp\Cookie\SessionCookieJar('SESSION_STORAGE', true);
$handler = new CurlHandler();
$stack = HandlerStack::create($handler);
$client = new Client(['cookies'=>true, 'handler' => $stack]);
$filename = 'files/huge-1gig-file.jpg';
$filesize = filesize($filename);
$fh = fopen($filename, 'r');
$chunkSize = 1024 * 2000;
$boundary = '----iCEBrkUploaderBoundary' . uniqid();
$url = 'https://localhost/app_dev.php/_uploader/bigupload/upload';
rewind($fh); // probably not necessary
while (! feof($fh)) {
$pos = ftell($fh);
$chunk = fread($fh, $chunkSize);
$calc = $pos + strlen($chunk)-1;
// Not sure if this is needed.
//if (ftell($fh) > $chunkSize) {
// $pos++;
//}
$request = $client->request(
'POST',
$url,
[
'cookies' => $jar,
'debug' => false,
'verify' => false,
'headers' => [
'Transfer-Encoding' => 'chunked',
'Accept-Encoding' => 'gzip, deflate, br',
'Accept' => 'application/json, text/javascript, */*; q=0.01',
'Connection' => 'keep-alive',
'Content-disposition' => 'attachment; filename="' . basename($filename) . '"',
'Content-length' => $calc - $pos,
'Content-Range' => 'bytes ' . $pos . '-' . $calc . '/' . $filesize
],
'multipart' => [
[
'name' => 'api_key,
'contents' => 'aaabbbcc-deff-ffed-dddd-1234567890123'
],
[
'name' => 'file',
'contents' => $chunk,
'filename' => basename($filename),
'headers' => [
'Content-Type' => 'multipart/form-data; boundary=' . $boundary
]
]
]
]
);
}
return new Response('ok', 200);
}
我希望这对其他人有所帮助。 Comments/Suggestions 欢迎。