发出请求并处理可恢复上传的响应:Google Drive api [php]
我正在使用 PHP 的 API 客户端库(测试版)来使用 google drive api,到目前为止,我可以授权和上传块中的文件.根据documentation,上传文件应该采取这三个步骤:
I'm using the API Client Library for PHP (Beta) to work with google drive api, So far I can authorize and and upload a file in chuncks. According to the documentation, these three steps should be taken to upload a file:
- 开始一个可恢复的会话.
- 保存可恢复的会话 URI.
- 上传文件.
我认为客户端库可以处理.同样,根据文档,如果我想显示进度或 恢复上传中断,或者为了处理错误,我需要捕获响应并能够发送这样的请求:
Which I think the Client Library handles. Again, according to the documentation, if I want to show the progress or resume an interrupted upload, or to handle errors I need to capture the response and also be able to send requests like this:
> PUT {session_uri} HTTP/1.1 Content-Length: 0 Content-Range: bytes
> */2000000
但我不知道我应该如何提出这样的请求以及从哪里得到响应,我用来上传的 php 代码,就像任何其他 php 代码一样,只在执行完成时返回值,即上传完成后.这是我用来上传文件的功能(可恢复):
But I have no idea how should I make such request and where can I get the response from, the php code I'm using to upload,like any other php code, only returns values when it is done executing, which is when the upload is done. here is the function I'm using to upload files (Resumable):
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 文件来处理这些请求吗?如果是这样,应该如何判断我正在请求哪个文件的状态?谢谢.
Should i make a separate php file to handle these requests? if so, How should tell that which file's status I'm requesting for? Thanks.
推荐答案
显然,BETA 客户端 API 根本不支持恢复上传.请参阅 Github 上的 此问题,它要求解决此问题.当然,修改类(见下文)并创建一个 Pull-request 以支持在提供会话 URL 时恢复现有上传,这应该很容易.
Apperantly, the BETA Client API simply doesn't support resuming Uploads. Please see this issue on Github, which asks for fixing this. Of course it should be easy to modify the class (see below) and create a Pull-request to enable support for resuming existing uploads when the session-URL is supplied.
但是,有一种简单的方法可以在上传块后获取进度.Google_Http_MediaFileUpload
-对象(在您的示例中为 $media
)有一个名为getProgress"的公共方法,可以随时调用.(请查看 API-client-library 的源代码).
However, there's an easy way to get the progress after an chunk has been uploaded.
The Google_Http_MediaFileUpload
-object ($media
in your example) has a public method called 'getProgress' which can be called anytime.
(Please have a look at the source code of the API-client-library).
为了获取上传状态,我会添加一个参数来通过调整块大小来修改进度精度.由于使用的块越多,产生的协议开销就越多,应避免将精度设置得越低.
To get the upload status, I'd add a parameter to modify the progress precision by adjusting the chunk size. Since the more chunks are used, the more protocol overhead is generated, setting the precision as low as possible should be avoided.
因此,您可以如下修改源代码以输出每个块后的进度:
Therefore, you could modify your source code as below to output the progress after each chunk:
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';
}
}
希望这会有所帮助.我会看看能不能找到一些时间来为客户端库添加简历支持.
Hope this helps. I'll see if I can find some time to add resume-support to the client Library.
根据 this doc,块至少需要256KB 大.修改了代码.
according to this doc, the chunks need to be at least 256KB big. Changed in code.
我刚刚添加了一个 拉取请求来添加简历功能.如果它被拒绝,您仍然可以决定是否可以修改/扩展客户端.如果它被接受,只需将 $media->getResumeUri()
的返回值存储在数据库中,然后调用 $media->resume($previously_stored_return_value)
实例化后恢复进程.
I just added a Pull request To add the Resume-Feature. If it gets rejected you could still decide whether it would be ok for you to modify/extend the client. If it gets accepted, just use store the return value of $media->getResumeUri()
in a database, and later call $media->resume($previously_stored_return_value)
after instantiation to resume the process.
相关文章