【问题标题】:Google Drive API download jpgGoogle Drive API 下载 jpg
【发布时间】:2020-05-21 17:30:03
【问题描述】:

我正在尝试使用 php 将 google drive jpg 下载到服务器,以便将其保存为可用的 jpg,例如手动下载时。

我可以从文件元中获取 getWebContentLink 并保存扩展名为 .jpg 的“a”文件:

$filemeta = $this->service->files->get($id,[
    "fields"=>"*"
]);
$filename = public_path().'/test.jpg';
$url=$filemeta->getWebContentLink();
file_put_contents($filename, fopen($url, 'r'));

然而这不是一个真正的 jpg 并且确实不能使用 <img src="/test.jpg" /> 元素显示。

设置:

public function __construct() {
        $this->getClient();
        $this->service= new Google_Service_Drive($this->client);
    }

    /**
     * @return Google_Client
     * @throws \Google_Exception
     */
    protected function getClient() {
        $client = new Google_Client();
        $client->setApplicationName('Google Drive API PHP Quickstart');
        //20200521$client->setScopes(Google_Service_Drive::DRIVE_METADATA_READONLY);
       $client->setScopes(Google_Service_Drive::DRIVE_READONLY);


       // https://www.googleapis.com/auth/drive.readonly
        $client->setAuthConfig(base_path().'/apicredentials/google/credentials.json');
        $client->setAccessType('offline');
        $client->setPrompt('select_account consent');

        // 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 = base_path().'/apicredentials/google/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.
        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()));
        }
        $this->client=$client;
    }

【问题讨论】:

    标签: php download google-drive-api jpeg


    【解决方案1】:

    这个答案怎么样?

    问题和解决方法:

    为了从外部检索带有webContentLink 的文件内容,需要使用访问令牌或文件需要公开共享。所以在你的脚本中,我认为创建的文件是登录页面的HTML数据。

    那么下面的解决方法怎么样?

    1. 使用访问令牌下载带有webContentLink 的文件内容。

    2. 首先,在 Google Drive 上公开共享文件。然后,使用您当前的脚本下载文件内容。

    3. 使用 Drive API 直接下载文件内容。在这种情况下,修改后的脚本如下。如果你使用https://www.googleapis.com/auth/drive.metadata.readonly作为范围,请修改为https://www.googleapis.com/auth/drive.readonly

      $content = $this->service->files->get($id, array("alt" => "media"));
      $filename = public_path().'/test.jpg';
      file_put_contents($filename, $content->getBody());
      

    参考:

    【讨论】:

    • 是这三种不同的解决方法,对#1特别感兴趣-如何使用令牌获取实际的img下载。关于 #2 我真的不想玩权限,因为这将是 3 个调用 - 公开/下载/恢复权限。#3 不确定如何或在哪里更改范围。
    • @Datadimension 感谢您的回复。从您的回复中,我可以看到您的整个脚本吗?因为当我看到它时,我认为你的脚本对模式1和3的修改点可能可以提出。从您的回复和提问中,我无法理解授权的范围和脚本。我必须为此道歉。如果可以,请将其添加到您的问题中。顺便说一句,当使用模式 1 时,需要 2 次 API 调用。另一方面,当使用模式 3 时,只需要一次 API 调用。如果您能合作解决您的问题,我很高兴。
    • 到目前为止感谢您的帮助,已更新问题集,到目前为止您尝试 3 回答
    • @Datadimension 感谢您回复并添加更多信息。从您的脚本中,我可以理解您使用 Google_Service_Drive::DRIVE_READONLY 作为范围。我认为在这个范围内,您可以直接使用模式 3。那么您可以使用您的$this->service 测试模式 3 吗?
    • 编辑回答颠倒了,对不起!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    • 2015-02-06
    • 2022-01-03
    相关资源
    最近更新 更多