如何修复PHP中使用Google Drive API上传大文件的类型错误?
Google Drive大文件分片上传代码错误修复
问题描述
我需要向Google Drive上传一个超过10GB的大文件,参考谷歌文档编写了如下代码:
public function upload($pathToFile) { $client = $this->client; $service = $this->drive; $fname = basename($pathToFile); $file = new Google_Service_Drive_DriveFile([ 'name' => $fname, ]); $chunkSizeBytes = 1 * 1024 * 1024 * 200; $request = $service->files->create($file); $fileId = $request->id; $media = new Google_Http_MediaFileUpload( $client, $request, 'text/plain', null, true, $chunkSizeBytes ); $media->setFileSize(filesize($pathToFile)); $status = false; $handle = fopen($pathToFile, "rb"); while (!$status && !feof($handle)) { $chunk = fread($handle, $chunkSizeBytes); $status = $media->nextChunk($chunk); } return $status != false; }
运行时出现以下错误:
Fatal error: Uncaught TypeError: Argument 2 passed to Google\Http\MediaFileUpload::__construct() must implement interface Psr\Http\Message\RequestInterface, instance of Google\Service\Drive\DriveFile given, called
错误原因
你错误地将$service->files->create($file)的执行结果(一个Google_Service_Drive_DriveFile对象)传给了Google_Http_MediaFileUpload的构造函数,但该构造函数要求的是未执行的PSR请求对象,而非执行后返回的文件实例。
修复方案
核心修改点
- 调用
create方法时,需传入uploadType参数指定为'resumable'(分片上传的必要配置),并通过->getRequest()获取原始请求对象,而不是直接执行请求。 - 移除提前获取
$fileId的代码,文件ID需在分片上传完成后从返回的$status对象中获取。
修复后的完整代码
public function upload($pathToFile) { $client = $this->client; $service = $this->drive; $fname = basename($pathToFile); $file = new Google_Service_Drive_DriveFile([ 'name' => $fname, ]); $chunkSizeBytes = 200 * 1024 * 1024; // 200MB分片大小,可根据实际调整 // 获取未执行的可恢复上传请求对象 $request = $service->files->create($file, [ 'uploadType' => 'resumable' ])->getRequest(); $media = new Google_Http_MediaFileUpload( $client, $request, 'text/plain', // 替换为你实际的文件MIME类型 null, true, $chunkSizeBytes ); $media->setFileSize(filesize($pathToFile)); $status = false; $handle = fopen($pathToFile, "rb"); while (!$status && !feof($handle)) { $chunk = fread($handle, $chunkSizeBytes); $status = $media->nextChunk($chunk); } fclose($handle); // 关闭文件句柄,避免资源泄漏 return $status !== false; }
额外注意事项
- 务必将
'text/plain'替换为上传文件对应的MIME类型(如视频用video/mp4、压缩包用application/zip),否则可能导致Google Drive无法正确识别文件类型。 - 分片大小可根据服务器内存、网络带宽调整,建议控制在100MB-500MB之间,避免过大引发内存溢出。
- 上传完成后,若需要文件ID,可通过
$status->id获取。
内容的提问来源于stack exchange,提问作者user153742
相关产品推荐
相关产品推荐

