为可恢复上传发出请求并处理响应:googledriveapi[php]

为可恢复上传发出请求并处理响应:googledriveapi[php],php,file-upload,google-drive-api,Php,File Upload,Google Drive Api,我正在使用API Client Library for PHP(Beta版)与google drive API一起工作,到目前为止,我可以在chuncks中授权并上传一个文件。 根据,上传文件应采取以下三个步骤: 启动可恢复的会话 保存可恢复会话URI 上传文件 我认为客户端库可以处理这个问题。 同样,根据文档,如果我想显示进度或处理错误,我需要捕获响应并能够发送如下请求: > PUT {session_uri} HTTP/1.1 Content-Length: 0 Content-R

我正在使用API Client Library for PHP(Beta版)与google drive API一起工作,到目前为止,我可以在chuncks中授权并上传一个文件。 根据,上传文件应采取以下三个步骤:

  • 启动可恢复的会话
  • 保存可恢复会话URI
  • 上传文件
我认为客户端库可以处理这个问题。 同样,根据文档,如果我想显示进度或处理错误,我需要捕获响应并能够发送如下请求:

> PUT {session_uri} HTTP/1.1 Content-Length: 0 Content-Range: bytes
> */2000000
但是我不知道我应该如何发出这样的请求,从哪里可以得到响应,我用来上传的php代码,就像任何其他php代码一样,只在执行完成时返回值,也就是上传完成时返回值。 以下是我用来上传文件的功能(可恢复):

函数上传文件($service、$client、$filetoUpload、$parentId){
$file=新的Google_服务_驱动器_驱动器文件();
$file->title=$filetoUpload['name'];
$chunkSizeBytes=1*1024*1024;
//设置父文件夹。
如果($parentId!=null){
$parent=新的Google_服务_驱动器_ParentReference();
$parent->setId($parentId);
$file->setParents(数组($parent));
}
//使用媒体上载调用API,延迟,使其不会立即返回。
$client->setDefer(true);
$request=$service->files->insert($file);
//创建一个媒体文件上传来代表我们的上传过程。
$media=新的Google\u Http\u MediaFileUpload(
$client,
$request,
$filetoUpload['type'],
无效的
是的,
$chunkSizeBytes
);
$media->setFileSize(filesize($filetoUpload['tmp_name']);
//上载各个块。$状态将为false,直到进程结束
//完成。
$status=false;
$handle=fopen($filetoUpload['tmp_name'],“rb”);
while(!$status&&!feof($handle)){
设置时间限制(120);
$chunk=fread($handle,$chunkSizeBytes);
$status=$media->nextChunk($chunk);
}
//$status的最终值将是来自对象API的数据
//已经上传了。
$result=false;
如果($status!=false){
$result=$status;
设置时间限制(30);
回声“;
打印(结果);
}
fclose($handle);
//重置到客户端以在将来立即执行请求。
$client->setDefer(false);
}
我应该创建一个单独的php文件来处理这些请求吗? 如果是这样的话,应该如何判断我请求的是哪个文件的状态? 谢谢。

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

然而,有一种简单的方法可以在上传一个区块后获得进度。
Google\u Http\u MediaFileUpload
-对象(
$media
在您的示例中)有一个名为“getProgress”的公共方法,可以随时调用。 (请查看API客户端库的详细信息)

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

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

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';
  }
 }

希望这有帮助。我将看看是否能抽出时间向客户端库添加简历支持

编辑:根据,块需要至少256KB大。代码更改


EDIT2:我刚刚添加了一个新功能来添加简历功能。如果被拒绝,您仍然可以决定是否可以修改/扩展客户端。如果它被接受,只需使用在数据库中存储
$media->getResumeUri()
的返回值,然后在实例化后调用
$media->resume($previous\u storage\u return\u value)
来恢复该过程。

在第一个实例中,进行上载调用并获取
resumeUri

 if ($resumeUri) {
    $media->resume($resumeUri);
 }

 fseek($handle, $offset);       
 $chunk = fread($handle, 1*1024*1024);

 $result = $media->nextChunk($chunk);
在第二个实例中,通过调用
nextChunk()
函数之前的
resume()
函数,使用相同的
resumeUri
从我们遗漏的位置恢复上载:


重复此过程,直到
$result
变量具有truthy值。

感谢您的回答,我认为应该从单独的php或函数调用progress,因为这只会在脚本执行完毕(即整个文件上载时)时返回所有状态数据。对于可恢复的上传,您认为最好使用node.js或javascript(+python)还是使用php?那些库支持可恢复上传吗?我认为这会让人头疼,而不是让它变得更简单。输出在完成所有操作后出现的原因是输出缓冲(搜索以查看如何禁用它)。要恢复上传,需要保存一些会话信息,最好的地方是数据库。最简单的方法是序列化整个
$media
对象,并在另一个脚本中将其取消序列化以继续。如果不能禁用输出缓冲(可能在共享主机环境中),您仍然可以更改行
echo'suc
。。。将进度保存到数据库中,并修改客户端(假设为JavaScript)以每秒请求该状态。@Rammingh:您看过PR了吗?谢谢,我现在正在旅行,所以我会在几天内尝试您的解决方案,不管怎样,还是获得了赏金,谢谢您的时间。@Ramtin Gh希望这能有所帮助,万一你还没有找到解决办法
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';
  }
 }
  $chunk  = fread($handle, 1*1024*1024);
  $result = $media->nextChunk($chunk);

  $resumeUri = $media->getResumeUri();
  $offset    = ftell($handle);
 if ($resumeUri) {
    $media->resume($resumeUri);
 }

 fseek($handle, $offset);       
 $chunk = fread($handle, 1*1024*1024);

 $result = $media->nextChunk($chunk);