13

I'm trying to understand the download flow for the Google Drive API v3 using PHP. Using the API v2 to download a file I:

  • Got the file metadata
  • Used the downloadUrl parameter to get a direct link to the file, attached an oAuth token to it and made a GET request to that.

Using API v3 this appears to have been deprecated, and according to the docs you call files->get() on the Drive Service with an array parameter of "alt" => "media" to get the file itself rather than the metadata.

And their example was:

$fileId = '0BwwA4oUTeiV1UVNwOHItT0xfa2M';
$content = $driveService->files->get($fileId, array(
'alt' => 'media' ));

I'm having trouble understanding how this works though and have trawled through the code but it didn't give much more info.

When you call get(), what actually goes into $content in the example? Is it the contents of the file (in which case this seems troublesome when dealing with large files - surely you'll get out of memory?!) or is it some type of stream reference that I can call fopen on? How would I save this file to disk?

The documentation doesn't really go into any detail about what happens when you make that API call, it just says it performs a file download?

adjuremods
  • 2,938
  • 2
  • 12
  • 17
jeonatl3
  • 575
  • 1
  • 4
  • 10

1 Answers1

31

I figured it out after a bit of experimenting.

When you call the get() method with the alt=>media parameter as specified in the docs you get the underlying HTTP response which is a Guzzle response object (as apparently the client library uses Guzzle for it's underlying transport).

From there you can call any Guzzle response method such as $response->getStatusCode() or you can get a stream of the actual file content.

Would have been helpful if they had documented this somewhere!

EDIT: Here's a rough example if anyone else gets stuck of how to save a file.

<?php

date_default_timezone_set("Europe/London");
require_once 'vendor/autoload.php';

// I'm using a service account, use whatever Google auth flow for your type of account.

putenv('GOOGLE_APPLICATION_CREDENTIALS=/path/to/service/account/key.json');
$client = new Google_Client();
$client->addScope(Google_Service_Drive::DRIVE);
$client->useApplicationDefaultCredentials();

$service = new Google_Service_Drive($client);

$fileId = "0Bxxxxxxxxxxxxxxxxxxxx"; // Google File ID
$content = $service->files->get($fileId, array("alt" => "media"));

// Open file handle for output.

$outHandle = fopen("/path/to/destination", "w+");

// Until we have reached the EOF, read 1024 bytes at a time and write to the output file handle.

while (!$content->getBody()->eof()) {
        fwrite($outHandle, $content->getBody()->read(1024));
}

// Close output file handle.

fclose($outHandle);
echo "Done.\n"

?>
jeonatl3
  • 575
  • 1
  • 4
  • 10
  • 1
    Thanks, I needed that additional information but for some reason reading in 1024 blocks did not work for me. I changed the code to fwrite($outHandle, $content->getBody()) without the while and it worked. – Miguel Febres Dec 12 '16 at 01:06
  • 1
    Thanks!! Very helpful. – Matt H Jan 01 '17 at 05:00
  • perfect. the loop you have here should be in the official docs for downloading large files. – Alex Aug 03 '19 at 23:30
  • could you please provide complete code what is key.json is it file which contains client id and secret key of google – insoftservice Jan 15 '22 at 11:25