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
相关产品推荐
相关产品推荐

