如何使用Google Drive API v3编程分享文件?报错求助
解决Google Drive API文件分享报错问题
报错根源分析
你的代码出现的错误主要来自四个方面:
- 凭证加载失败:使用
useApplicationDefaultCredentials()但未正确配置默认凭证,Web应用应使用OAuth2授权流程 - Permission对象初始化错误:传入了二维数组,导致对象属性解析异常
- 参数赋值错误:修改权限对象时引用了错误的变量
- 请求参数格式错误:批量请求的参数使用了多余的数组嵌套
修复后的完整代码
use Google\Client; use Google\Service\Drive; require_once 'vendor/autoload.php'; function shareFile() { try { $client = new Client(); // 配置OAuth2客户端信息 $client->setClientId('你的Web客户端ID'); $client->setClientSecret('你的Web客户端密钥'); $client->setRedirectUri('http://localhost/google-drive/callback.php'); // 需与开发者控制台配置一致 $client->addScope(Drive::DRIVE_FILE); // 建议使用最小必要权限,DRIVE_FILE比DRIVE更安全 $client->setAccessType('offline'); $client->setPrompt('select_account consent'); // 处理授权流程 session_start(); if (!isset($_SESSION['access_token'])) { $authUrl = $client->createAuthUrl(); header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL)); exit; } else { $client->setAccessToken($_SESSION['access_token']); // 刷新过期的token if ($client->isAccessTokenExpired()) { $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken()); $_SESSION['access_token'] = $client->getAccessToken(); } } $driveService = new Drive($client); // 获取用户输入(修正readline用法,提示文本与默认值分离) $realFileId = readline("请输入文件ID(默认:1Mk2rrKibgh5SMKV4zKPBUVyc31-hvzeK):"); $realFileId = empty($realFileId) ? '1Mk2rrKibgh5SMKV4zKPBUVyc31-hvzeK' : $realFileId; $realUser = readline("请输入目标用户邮箱(默认:mydrive_email@gmail.com):"); $realUser = empty($realUser) ? 'mydrive_email@gmail.com' : $realUser; $realDomain = readline("请输入域名:"); $ids = []; $fileId = $realFileId; $driveService->getClient()->setUseBatch(true); try { $batch = $driveService->createBatch(); // 初始化用户权限(修正二维数组为一维数组) $userPermission = new Drive\Permission([ 'type' => 'user', 'role' => 'writer', 'emailAddress' => $realUser ]); // 修正请求参数格式,去掉多余数组嵌套 $request = $driveService->permissions->create( $fileId, $userPermission, ['fields' => 'id'] ); $batch->add($request, 'user'); // 初始化域名权限(修正变量引用错误) if (!empty($realDomain)) { $domainPermission = new Drive\Permission([ 'type' => 'domain', 'role' => 'reader', 'domain' => $realDomain ]); $request = $driveService->permissions->create( $fileId, $domainPermission, ['fields' => 'id'] ); $batch->add($request, 'domain'); } $results = $batch->execute(); foreach ($results as $key => $result) { if ($result instanceof Google\Service\Exception) { printf("【%s】错误:%s\n", $key, $result->getMessage()); } else { printf("【%s】权限ID:%s\n", $key, $result->id); $ids[] = $result->id; } } } finally { $driveService->getClient()->setUseBatch(false); } return $ids; } catch (Exception $e) { echo "错误信息:" . $e->getMessage(); } } // 回调页面处理(需单独创建callback.php) // callback.php内容: /* <?php session_start(); require_once 'vendor/autoload.php'; $client = new Google\Client(); $client->setClientId('你的Web客户端ID'); $client->setClientSecret('你的Web客户端密钥'); $client->setRedirectUri('http://localhost/google-drive/callback.php'); if (isset($_GET['code'])) { $token = $client->fetchAccessTokenWithAuthCode($_GET['code']); $_SESSION['access_token'] = $token; header('Location: quickstart.php'); // 跳转回主脚本 exit; } ?> */ shareFile(); ?>
关键修复点说明
凭证配置修正
- 替换
useApplicationDefaultCredentials()为OAuth2客户端ID/密钥配置,符合Web应用的授权流程 - 添加session管理token,支持离线刷新
- 使用更安全的
DRIVE_FILE权限范围,遵循最小权限原则
- 替换
Permission对象初始化修正
- 去掉数组嵌套,直接传入一维数组
['type' => 'user', ...],避免属性解析异常
- 去掉数组嵌套,直接传入一维数组
参数赋值修正
- 给域名权限赋值时,正确引用
$domainPermission变量,而非错误的$userPermission
- 给域名权限赋值时,正确引用
请求参数格式修正
- 批量请求的第三个参数改为一维数组
['fields' => 'id'],去掉多余的数组包裹
- 批量请求的第三个参数改为一维数组
用户输入处理修正
- 调整readline的提示文本,将默认值与提示分离,处理输入为空的情况
额外注意事项
- 确保开发者控制台中已添加正确的重定向URI(与代码中的
setRedirectUri一致) - 首次运行需访问脚本,完成OAuth2授权流程
- 若使用服务账号而非Web应用,需将凭证改为服务账号JSON文件,并设置
$client->setAuthConfig('service-account.json')
内容的提问来源于stack exchange,提问作者GemeAlex
相关产品推荐
相关产品推荐

