PHP:发送大文件时出错

00jrzges  于 2023-03-11  发布在  PHP
关注(0)|答案(2)|浏览(153)

使用Guzzle将文件上传到REST API:
我的PHP代码是:

  1. use GuzzleHttp\Client;
  2. use GuzzleHttp\RequestOptions;
  3. use GuzzleHttp\Psr7;
  4. $apiClient = new Client([
  5. 'base_uri' => $url,
  6. 'timeout' => 5, // seconds
  7. 'headers' => [
  8. 'Content-Type' => 'application/json',
  9. 'Accept' => 'application/json',
  10. ],
  11. ]);
  12. $postParams = [
  13. RequestOptions::MULTIPART => [
  14. ...$multipartParams,
  15. [
  16. 'name' => 'upload',
  17. 'contents' => Psr7\Utils::streamFor(fopen($filePath, 'r')),
  18. 'filename' => $postFields['filename'],
  19. ]
  20. ]
  21. ];
  22. $response = $apiClient->post("upload", $postParams);

对于大于10 MB的文件,此代码会导致错误:

  1. Error: #0 /app/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php(158): GuzzleHttp\Handler\CurlFactory::createRejection(Object(GuzzleHttp\Handler\EasyHandle), Array)
  2. #1 /app/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php(110): GuzzleHttp\Handler\CurlFactory::finishError(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
  3. #2 /app/vendor/guzzlehttp/guzzle/src/Handler/CurlHandler.php(47): GuzzleHttp\Handler\CurlFactory::finish(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
  4. #3 /app/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php(28): GuzzleHttp\Handler\CurlHandler->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
  5. #4 /app/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php(48): GuzzleHttp\Handler\Proxy::GuzzleHttp\Handler\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
  6. #5 /app/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php(64): GuzzleHttp\Handler\Proxy::GuzzleHttp\Handler\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
  7. #6 /app/vendor/guzzlehttp/guzzle/src/Middleware.php(31): GuzzleHttp\PrepareBodyMiddleware->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
  8. #7 /app/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php(71): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
  9. #8 /app/vendor/guzzlehttp/guzzle/src/Middleware.php(63): GuzzleHttp\RedirectMiddleware->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
  10. #9 /app/vendor/guzzlehttp/guzzle/src/HandlerStack.php(75): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
  11. #10 /app/vendor/guzzlehttp/guzzle/src/Client.php(331): GuzzleHttp\HandlerStack->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
  12. #11 /app/vendor/guzzlehttp/guzzle/src/Client.php(168): GuzzleHttp\Client->transfer(Object(GuzzleHttp\Psr7\Request), Array)
  13. #12 /app/vendor/guzzlehttp/guzzle/src/Client.php(187): GuzzleHttp\Client->requestAsync('POST', Object(GuzzleHttp\Psr7\Uri), Array)
  14. #13 /app/vendor/guzzlehttp/guzzle/src/ClientTrait.php(95): GuzzleHttp\Client->request('POST', 'upload', Array)
  15. #14 /app/CkanApiClient.php(140): GuzzleHttp\Client->post('upload', Array)
  16. #15 /app/ckan-upload.php(142): CkanApiClient->send('upload', Array)
  17. #16 {main}

在命令行上使用curl执行文件上载时,上载工作正常。
如何使我的代码工作?如何调试错误?
我的环境:

  • composer :狂饮http/狂饮7.5.0
  • 停靠文件:php:8.2-cli
  • PHP:数据库扩展
g2ieeal7

g2ieeal71#

我认为你的php配置阻止了上传。guzzlehttp没有。

注意:cli中的curl命令没有限制

您需要在php.ini中增加upload_max_filesizepost_max_size

  1. upload_max_filesize = 100M
  2. post_max_size = 100M

然后重新启动你的php-fpm或者任何运行php的程序。
您不能在运行时更改这些值;上传大于php.ini中指定值的文件将失败。
Read more about php.ini directives

ivqmmu1c

ivqmmu1c2#

已解决

问题是5秒的超时。大文件需要更长的时间才能上传。
将超时设置为30秒的解决方案是:

  1. $apiClient = new Client([
  2. 'base_uri' => $url,
  3. 'timeout' => 30, // seconds
  4. 'headers' => [
  5. 'Content-Type' => 'application/json',
  6. 'Accept' => 'application/json',
  7. ],
  8. ]);

相关问题