繁体   English   中英

PHP - Google App Engine 将大文件作为块上传到 Google Drive(可恢复上传)- 500 错误

[英]PHP - Google App Engine Uploading large files to Google Drive as chunks (Resumable Upload) - 500 Error

我正在使用在后台运行的 php 代码将文件从 Google Cloud 存储桶上传到 Google Drive 文件夹。 我的问题是当文件大小增加时,Google Drive(或 GAE)会给出 500 错误。

Error: Server Error
The server encountered an error and could not complete your request.
Please try again in 30 seconds.

我正在使用以下依赖项。

"nao-pon/flysystem-google-drive": "^1.1",

以下是我的代码部分,导致此错误。 这适用于小文件:

$fileN = $this->clean($att->ATT_TITLE);

$fileData = file_get_contents("https://storage.googleapis.com/xxxxxx/".$att->ATT_FILE);

$dir = sys_get_temp_dir();
$tmp = tempnam($dir, $fileN);
file_put_contents($tmp, $fileData);
Storage::cloud()->putFileAs( $folderPath, new File($tmp),$fileN);

我已经在 .env 文件中设置了配置

FILESYSTEM_CLOUD=google
GOOGLE_DRIVE_CLIENT_ID=xxxxapps.googleusercontent.com
GOOGLE_DRIVE_CLIENT_SECRET=xxxxx
GOOGLE_DRIVE_REFRESH_TOKEN=xxxxxx
GOOGLE_DRIVE_FOLDER_ID=xxxx
#GOOGLE_DRIVE_TEAM_DRIVE_ID=xxx

我已经在 filesystem.php 中设置了如下磁盘

'google' => [
        'driver' => 'google',
        'clientId' => env('GOOGLE_DRIVE_CLIENT_ID'),
        'clientSecret' => env('GOOGLE_DRIVE_CLIENT_SECRET'),
        'refreshToken' => env('GOOGLE_DRIVE_REFRESH_TOKEN'),
        'folderId' => env('GOOGLE_DRIVE_FOLDER_ID'),
    // 'teamDriveId' => env('GOOGLE_DRIVE_TEAM_DRIVE_ID'),
    ],

我已将 php.ini 文件设置如下

upload_max_filesize = 300M
post_max_size = 300M
memory_limit = 3000M

应用程序.yaml

runtime: php72
handlers: 
- url: /assets
  static_dir: public/assets
env_variables:
   APP_KEY: xxxxx
   APP_STORAGE: /tmp
   CACHE_DRIVER: file
   VIEW_COMPILED_PATH: /tmp
   SESSION_DRIVER: database
   DB_DATABASE: xxx
   DB_USERNAME: xx
   DB_PASSWORD: xxxx
   DB_SOCKET: "/cloudsql/xxxxx"
runtime_config:
    document_root: public

谁能给我一个提示或给我另一种方法来做到这一点? 我的要求基本上是通过 Google App Engine 中的后台作业将大文件(如 250MB)上传到 Google Drive。

由于您正在调用 Cloud Storage API 来上传可以在 60 秒内完成上传的大文件,这是 Google Cloud Storage API 的默认超时时间。 您可以自行修改 API 超时。 这里是stackoverflow的案例供大家参考,自己设置API超时。

对于这种情况,分块上传解决了这个问题。

请参阅以下 Google API PHP 客户端示例https://github.com/googleapis/google-api-php-client/blob/master/examples/large-file-upload.php

示例工作代码:

$fileData = file_get_contents("https://storage.googleapis.com/xxxx/".$att->ATT_FILE);

$dir = sys_get_temp_dir();
$tmp = tempnam($dir, $fileN);
file_put_contents($tmp, $fileData);       
     
$fileToUpload = new File($tmp);
$filename = $fileN;
$mimeType = mime_content_type($tmp);
                   
$driveService = Storage::cloud();
$client = new \Google_Client();
$client->setClientId('xxxx');
$client->setClientSecret('xxx');
$client->refreshToken('xxx');
$client->setApplicationName('xxx');

$service = new \Google_Service_Drive($client);


// Test 1
$file = new \Google_Service_Drive_DriveFile();
$file->title = $fileN;
$file->name = $fileN;
$file->parents = array($basePath);
$chunkSizeBytes = 1 * 1024 * 1024;

// Call the API with the media upload, defer so it doesn't immediately return.
$client->setDefer(true);
$request = $service->files->create($file);

// Create a media file upload to represent our upload process.
$media = new \Google_Http_MediaFileUpload(
  $client,
  $request,
  $mimeType,
  null,
  true,
  $chunkSizeBytes
);
$media->setFileSize(filesize($tmp));

// Upload the various chunks. $status will be false until the process is
// complete.
$status = false;
$handle = fopen($tmp, "rb");
while (!$status && !feof($handle)) {
  $chunk = fread($handle, $chunkSizeBytes);
  $status = $media->nextChunk($chunk);
 }

// The final value of $status will be the data from the API for the object
// that has been uploaded.
$result = false;
if($status != false) {
  $result = $status;
}

fclose($handle);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM