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

Google Drive API v3 PHP移动文件保留完整元数据的问题求解

Google Drive API v3 PHP移动文件保留元数据问题

我在使用Google API v3实现文件跨文件夹移动,当前基于Laravel封装类开发,已确认文件ID和目标父文件夹ID均正确。参考官方文档后我首先尝试了如下代码:

public function moveFileFromTo($fileID, $toParentID) {
    $fromFile = $this->service->files->get($fileID, ['fields' => '*']);
    $fromParentID = $fromFile->getParents();
    $blankFile = new Google_Service_Drive_DriveFile();
    $this->service->files->update($fileID, $blankFile, [
        "removeParents" => $fromParentID,
        "addParents" => $toParentID
    ]);
}

运行后文件成功移动,但所有元数据全部丢失。之后我又调整了写法:

public function moveFileFromTo($fileID, $toParentID) {
    $fromFile = $this->service->files->get($fileID, ['fields' => '*']);
    $fromParentID = $fromFile->getParents();
    $fromFile->setParents($fromParentID);
    $this->service->files->update($fileID, $fromFile);
}

这次运行直接抛出错误:

Google\Service\Exception
{ "error": { "errors": [ { "domain": "global", "reason": 
"fieldNotWritable", "message": "The resource body includes fields 
which are not directly writable." } ], "code": 403, "message": "The 
resource body includes fields which are not directly writable." } }

我的需求是移动文件的同时完整保留全部元数据。根据文档说明,update方法要么传入新的空文件对象(逻辑非常不合理),要么需要我手动剔除第二个参数$fromFile中不可直接写入的字段,哪怕我只修改了可写的父级属性。


现有回复方案存在的问题

之前收到的方案建议我调整get请求的字段:

$fromFile = $this->service->files->get($fileID, ['fields' => 'parents, id']);

但这段代码并没有如预期只返回id和parents两个字段,实际返回了约75个属性,其中大量是不可写的。我在PHPStorm中GET请求后立刻打了断点,确认这个问题和后续逻辑无关。
调试截图
我尝试手动删除不可写字段:

unset($fromFile->shared);

但删除后仍然残留其他不可写属性,且当前操作的文件实际并未被共享。
文件共享属性截图


当前实现进展

我自己调整了代码,目前已经可以正常运行:

public function moveFileFromTo($fileID, $toParentID) {
    $fromFile = $this->service->files->get($fileID, ["fields" => "id,parents"]);
    $fromFile = $this->getParsedWritableFile($fromFile);
    $fromFile->setParents($toParentID);
    $this->service->files->update($fileID, $fromFile, ['addParents' => $toParentID]);
}

其中getParsedWritableFile方法的作用是创建新的Google Drive文件对象,仅在新对象上设置可写属性,代码如下:

public function getParsedWritableFile($gdrivefile) {
        $gdrivefile = new \Google_Service_Drive_DriveFile();// 可注释或删除,仅用于自动补全函数名

        $parsedFile = new \Google_Service_Drive_DriveFile();
        // 仅保留官方文档标注的可写字段
        $parsedFile->setName($gdrivefile->getName());//name
        $parsedFile->setMimeType($gdrivefile->getMimeType());//mimeType
        $parsedFile->setDescription($gdrivefile->getDescription());//description
        $parsedFile->setStarred($gdrivefile->getStarred());//starred
        $parsedFile->setTrashed($gdrivefile->getTrashed());//trashed
        $parsedFile->setParents($gdrivefile->getParents());//parents
        $parsedFile->setProperties($gdrivefile->getProperties());//properties  [object]
        $parsedFile->setAppProperties($gdrivefile->getAppProperties());//appProperties [object]
        $parsedFile->setCreatedTime($gdrivefile->getCreatedTime());//createdTime
        $parsedFile->setModifiedTime($gdrivefile->getModifiedTime());//modifiedTime
        $parsedFile->setWritersCanShare($gdrivefile->getWritersCanShare());//writersCanShare
        $parsedFile->setViewedByMeTime($gdrivefile->getViewedByMeTime());//viewedByMeTime
        $parsedFile->setFolderColorRgb($gdrivefile->getFolderColorRgb());//folderColorRgb
        $parsedFile->setOriginalFilename($gdrivefile->getOriginalFilename());//originalFilename
        $parsedFile->setCopyRequiresWriterPermission($gdrivefile->getCopyRequiresWriterPermission());//copyRequiresWriterPermission

        /* 处理复杂权限字段 */
        $contenthints=$gdrivefile->getContentHints();
        if($contenthints){
            $parsedFile->setContentHints($contenthints->getThumbnail()->getImage());
            $parsedFile->setContentHints($contenthints->getThumbnail()->getMimeType());
            $parsedFile->setContentHints($contenthints->getIndexableText());
        }

        $parsedFile->setContentRestrictions($gdrivefile->getContentRestrictions());

        return $parsedFile;
    }

该方案目前初步验证有效,原始元数据如下:
原始元数据截图
代码可以成功移动文件,且元数据、创建时间、EXIF信息均完整保留。
移动后元数据截图

请问是否有更简洁的方案实现Google Drive API v3 PHP移动文件并保留全部元数据的需求?

内容的提问来源于stack exchange,提问作者Datadimension

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 16:06:01