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

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]

终端输出截图:
终端输出截图


问题排查与修复方案

  1. 作用域参数格式错误
    原代码中setScopes传入了两个独立参数,正确写法应该是传入数组:
$client->setScopes([Google_Service_Drive::DRIVE, "https://www.googleapis.com/auth/drive.readonly"]);

错误的参数格式会导致作用域未正确生效,无法获取需要权限的字段。

  1. CLI模式下无需设置Redirect URI
    CLI授权流程不需要setRedirectUri,直接删除该行代码即可,避免干扰授权流程。

  2. 区分文件类型获取对应链接

  • 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";
        }
    }
}
  1. 重新生成授权令牌
    修改作用域后,需要删除本地的token.json,重新运行脚本进行授权,确保新的作用域生效。

内容的提问来源于stack exchange,提问作者Chun Hin So

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 14:04:52