You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复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请求对象,而非执行后返回的文件实例。

修复方案

核心修改点

  1. 调用create方法时,需传入uploadType参数指定为'resumable'(分片上传的必要配置),并通过->getRequest()获取原始请求对象,而不是直接执行请求。
  2. 移除提前获取$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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 09:45:07