我正在使用 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/