PHP获取Google Drive文件URL失败求助:修改Quickstart代码无效
问题:Google Drive API无法输出文件URL
我修改了Google Drive PHP版的quickstart示例代码,想要在终端输出文件的URL,但实际运行后无法获取到链接,终端提示“can't generate URL”。以下是我的完整代码:
<?php /** * Copyright 2018 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // [START drive_quickstart] require_once __DIR__ . '/vendor/autoload.php'; if (php_sapi_name() != 'cli') { throw new Exception('This application must be run on the command line.'); } use Google\Client; use Google\Service\Drive; /** * Returns an authorized API client. * @return Client the authorized client object */ function getClient() { $client = new Google\Client(); $client->setApplicationName('Google Drive API PHP Quickstart'); $client->setScopes(Google_Service_Drive::DRIVE,"https://www.googleapis.com/auth/drive.readonly"); $client->setAuthConfig('credentials.json'); $client->setRedirectUri('http://127.0.0.1/home/ubuntu/intern/quickstart.php'); $client->setAccessType('offline'); $client->setPrompt('consent'); $client->setIncludeGrantedScopes(true); // Load previously authorized token from a file, if it exists. // The file token.json stores the user's access and refresh tokens, and is // created automatically when the authorization flow completes for the first // time. $tokenPath = 'token.json'; if (file_exists($tokenPath)) { $accessToken = json_decode(file_get_contents($tokenPath), true); $client->setAccessToken($accessToken); } // If there is no previous token or it's expired. try{ if ($client->isAccessTokenExpired()) { // Refresh the token if possible, else fetch a new one. if ($client->getRefreshToken()) { $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken()); } else { // Request authorization from the user. $authUrl = $client->createAuthUrl(); printf("Open the following link in your browser:\n%s\n", $authUrl); print 'Enter verification code: '; $authCode = trim(fgets(STDIN)); // Exchange authorization code for an access token. $accessToken = $client->fetchAccessTokenWithAuthCode($authCode); $client->setAccessToken($accessToken); // Check to see if there was an error. if (array_key_exists('error', $accessToken)) { throw new Exception(join(', ', $accessToken)); } } // Save the token to a file. if (!file_exists(dirname($tokenPath))) { mkdir(dirname($tokenPath), 0700, true); } file_put_contents($tokenPath, json_encode($client->getAccessToken())); } } catch(Exception $e) { // TODO(developer) - handle error appropriately echo 'Some error occured: '.$e->getMessage(); } return $client; } // Get the API client and construct the drive object. $client = getClient(); $drive = new Google\Service\Drive($client); // Print the names and IDs for up to 10 files. $optParams = array( 'pageSize' => 10, 'fields' => 'nextPageToken, files(id, name, webContentLink)' ); $results = $drive->files->listFiles($optParams); if (count($results->getFiles()) == 0) { print "No files found.\n"; } else { print "Files:\n"; foreach ($results->getFiles() as $file) { printf("%s (%s)", $file->getName(), $file->getId()); $webContentLink = $file->getWebContentLink(); if (!empty($webContentLink)) { printf("Web Content Link: %s\n", $webContentLink); } else{ echo"can't generate URL \n"; } } } // [END drive_quickstart]
终端输出截图:
问题排查与修复方案
- 作用域参数格式错误
原代码中setScopes传入了两个独立参数,正确写法应该是传入数组:
$client->setScopes([Google_Service_Drive::DRIVE, "https://www.googleapis.com/auth/drive.readonly"]);
错误的参数格式会导致作用域未正确生效,无法获取需要权限的字段。
CLI模式下无需设置Redirect URI
CLI授权流程不需要setRedirectUri,直接删除该行代码即可,避免干扰授权流程。区分文件类型获取对应链接
webContentLink仅适用于非Google原生文件(如PDF、图片、普通压缩包等),用于直接下载文件;- Google原生文件(如Docs、Sheets、Slides)需要使用
webViewLink,用于在浏览器中打开文件; - 文件夹没有这两个字段,需要单独处理。
修改后的文件列表请求和打印逻辑:
// 调整fields,同时请求webContentLink和webViewLink $optParams = array( 'pageSize' => 10, 'fields' => 'nextPageToken, files(id, name, webContentLink, webViewLink, mimeType)' ); $results = $drive->files->listFiles($optParams); if (count($results->getFiles()) == 0) { print "No files found.\n"; } else { print "Files:\n"; foreach ($results->getFiles() as $file) { printf("%s (%s)\n", $file->getName(), $file->getId()); $mimeType = $file->getMimeType(); // 处理文件夹 if ($mimeType === 'application/vnd.google-apps.folder') { echo " 类型:文件夹,无直接访问链接\n"; continue; } // 处理非Google原生文件 $webContentLink = $file->getWebContentLink(); if (!empty($webContentLink)) { printf(" 下载链接:%s\n", $webContentLink); } // 处理Google原生文件 $webViewLink = $file->getWebViewLink(); if (!empty($webViewLink)) { printf(" 在线查看链接:%s\n", $webViewLink); } if (empty($webContentLink) && empty($webViewLink)) { echo " 无法获取有效链接\n"; } } }
- 重新生成授权令牌
修改作用域后,需要删除本地的token.json,重新运行脚本进行授权,确保新的作用域生效。
内容的提问来源于stack exchange,提问作者Chun Hin So
相关产品推荐
相关产品推荐

