php - 发出请求并处理可​​续传上传的响应 : Google Drive api [php]

标签 php file-upload google-drive-api

我正在使用 PHP 的 API 客户端库(测试版)与 google Drive api 配合使用,到目前为止,我可以授权并上传文件。 根据documentation ,上传文件应执行以下三个步骤:

  • Start a resumable session.
  • Save the resumable session URI.
  • Upload the file.

我认为客户端库可以处理。 再次,根据文档,如果我想显示进度或 resume an interrupted upload ,或者为了处理错误,我需要捕获响应并且还能够发送如下请求:

> PUT {session_uri} HTTP/1.1 Content-Length: 0 Content-Range: bytes
> */2000000

但是我不知道我应该如何发出这样的请求以及从哪里可以获得响应,我用来上传的php代码,像任何其他php代码一样,仅在执行完成时返回值,即当上传完成时。 这是我用来上传文件的函数(可恢复):

function uploadFile($service,$client,$filetoUpload,$parentId){
    $file = new Google_Service_Drive_DriveFile();
    $file->title = $filetoUpload['name'];
    $chunkSizeBytes = 1 * 1024 * 1024;
    
    // Set the parent folder.
      if ($parentId != null) {
        $parent = new Google_Service_Drive_ParentReference();
        $parent->setId($parentId);
        $file->setParents(array($parent));
      }
  
    // Call the API with the media upload, defer so it doesn't immediately return.
    $client->setDefer(true);
    $request = $service->files->insert($file);
    
    // Create a media file upload to represent our upload process.
    $media = new Google_Http_MediaFileUpload(
      $client,
      $request,
      $filetoUpload['type'],
      null,
      true,
      $chunkSizeBytes
    );
    $media->setFileSize(filesize($filetoUpload['tmp_name']));
    
    // Upload the various chunks. $status will be false until the process is
    // complete.
    $status = false;
    $handle = fopen($filetoUpload['tmp_name'], "rb");

    while (!$status && !feof($handle)) {
      set_time_limit(120);    
      $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;
      set_time_limit(30);
      echo "<pre>";
      print_r($result);
    }
    
    fclose($handle);
    // Reset to the client to execute requests immediately in the future.
    $client->setDefer(false);
}

我应该创建一个单独的 php 文件来处理这些请求吗? 如果是这样,应该如何知道我正在请求哪个文件的状态? 谢谢。

最佳答案

显然,测试版客户端 API 根本不支持恢复上传。 请参阅this issue在 Github 上,它要求修复这个问题。当然,应该很容易修改类(见下文)并创建拉请求,以在提供 session URL 时支持恢复现有上传。

但是,有一种简单的方法可以在上传 block 后获取进度。 Google_Http_MediaFileUpload 对象(示例中的 $media)有一个名为“getProgress”的公共(public)方法,可以随时调用。 (请查看 API 客户端库的 source code)。

为了获取上传状态,我添加了一个参数来通过调整 block 大小来修改进度精度。由于使用的 block 越多,产生的协议(protocol)开销就越大,应避免将精度设置得尽可能低。

因此,您可以如下修改源代码以在每个 block 之后输出进度:

function uploadFile($service,$client,$filetoUpload,$parentId,$progressPrecision = 1){
$file = new Google_Service_Drive_DriveFile();
$file->title = $filetoUpload['name'];
$filesize = filesize($filetoUpload['tmp_name']);
//minimum chunk size needs to be 256K
$chunkSizeBytes = min( $filesize / 100 * $progressPrecision, 262144);

// Set the parent folder.
  if ($parentId != null) {
    $parent = new Google_Service_Drive_ParentReference();
    $parent->setId($parentId);
    $file->setParents(array($parent));
  }

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

// Create a media file upload to represent our upload process.
$media = new Google_Http_MediaFileUpload(
  $client,
  $request,
  $filetoUpload['type'],
  null,
  true,
  $chunkSizeBytes
);
$media->setFileSize($filesize);

while (!$status && !feof($handle)) {
  set_time_limit(120);    
  $chunk = fread($handle, $chunkSizeBytes);
  $status = $media->nextChunk($chunk);
  if(!$status){ //nextChunk() returns 'false' whenever the upload is still in progress
   echo 'sucessfully uploaded file up to byte ' . $media->getProgress() . 
   ' which is ' . ( $media->getProgress() / $chunkSizeBytes ) . '% of the whole file';
  }
 }

希望这有帮助。我会看看是否能找到一些时间向客户端库添加简历支持。

编辑:根据this doc , block 至少需要 256KB 大。更改了代码。

EDIT2:我刚刚添加了 Pull request添加恢复功能。如果被拒绝,您仍然可以决定是否可以修改/扩展客户端。如果被接受,只需将 $media->getResumeUri() 的返回值存储在数据库中,然后调用 $media->resume($previously_stored_return_value)实例化以恢复进程。

关于php - 发出请求并处理可​​续传上传的响应 : Google Drive api [php],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32379007/

相关文章:

php - 如何在 PHP 中使用对象键创建类似数组的数据结构?

jquery - 仅在处理完所有文件后才发送错误或成功消息

file - PyQt 打开文件对话框 - 显示路径名称

javascript - 根据类别隐藏点击或加载时的数据

php - 使用 Bootstrap 为 `wp list` 类别设置样式

javascript - Navigator.userAgent.match - 特定手机识别

image - 带有上传图像预览的 Magnific Popup

c# - Google Drive 简单 API 访问授权失败

java - 如何在 google API v3 中搜索特定文件夹内的文件

google-docs-api - 如何更改文件的上次修改日期