简体   繁体   中英

Downloading a file with Google Drive API with PHP

I'm trying to make a system that allows me to keep my server synchronized (one-way) with a folder full of photos in Google drive.

So far I've managed to download the PHP client library from github (I don't use composer) and list some files. I managed to manually get the id of one of photos using this:

// Print the names and IDs for up to 10 files.
$optParams = array(
    'pageSize' => 10,
    'fields' => "nextPageToken, files(id, name)"
);
$results = $service->files->listFiles($optParams);

if (count($results->getFiles()) == 0) {
    print "No files found.\n";
} else {
    print "Files:\n";

    echo "<pre>";
    print_r($results);
    echo "</pre>";
}

However I'm unable to download the file from the ID, here's what I've tried, but I get an error saying
Fatal error: Call to undefined method Google_Service_Drive_DriveFile::getDownloadUrl()

<?php
require $_SERVER['DOCUMENT_ROOT'] . '/includes/googleAPI/vendor/autoload.php';

define('APPLICATION_NAME', 'Drive API PHP Quickstart');
define('CREDENTIALS_PATH', $_SERVER['DOCUMENT_ROOT'] . '/includes/googleAPI/drive-php-quickstart.json');
define('CLIENT_SECRET_PATH', $_SERVER['DOCUMENT_ROOT'] . '/includes/googleAPI/client_secret.json');
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/drive-php-quickstart.json
define('SCOPES', implode(' ', array(
        "https://www.googleapis.com/auth/drive.readonly")
));

/*if (php_sapi_name() != 'cli') {
    throw new Exception('This application must be run on the command line.');
}*/

/**
 * Returns an authorized API client.
 * @return Google_Client the authorized client object
 */
function getClient()
{
    $client = new Google_Client();
    $client->setApplicationName(APPLICATION_NAME);
    $client->setScopes(SCOPES);
    $client->setAuthConfigFile(CLIENT_SECRET_PATH);
    $client->setAccessType('offline');

    // Load previously authorized credentials from a file.
    $credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
    if (file_exists($credentialsPath)) {
        $accessToken = file_get_contents($credentialsPath);
    } 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->authenticate($authCode);

        // Store the credentials to disk.
        if (!file_exists(dirname($credentialsPath))) {
            mkdir(dirname($credentialsPath), 0700, true);
        }
        file_put_contents($credentialsPath, json_encode($accessToken));
        printf("Credentials saved to %s\n", $credentialsPath);
    }
    $client->setAccessToken($accessToken);

    // Refresh the token if it's expired.
    if ($client->isAccessTokenExpired()) {
        $refreshToken = $client->getRefreshToken();
        $client->refreshToken($refreshToken);
        $newAccessToken = $client->getAccessToken();
        $newAccessToken['refresh_token'] = $refreshToken;
        file_put_contents($credentialsPath, json_encode($newAccessToken));
    }
    return $client;
}

/**
 * Expands the home directory alias '~' to the full path.
 * @param string $path the path to expand.
 * @return string the expanded path.
 */
function expandHomeDirectory($path)
{
    $homeDirectory = getenv('HOME');
    if (empty($homeDirectory)) {
        $homeDirectory = getenv("HOMEDRIVE") . getenv("HOMEPATH");
    }
    return str_replace('~', realpath($homeDirectory), $path);
}

/**
 * Print a file's metadata.
 *
 * @param Google_Service_Drive $service Drive API service instance.
 * @param string $fileId ID of the file to print metadata for.
 */
function printFile($service, $fileId) {
    try {
        $file = $service->files->get($fileId);

        print "Title: " . $file->getName();
        print "Description: " . $file->getDescription();
        print "MIME type: " . $file->getMimeType();
        print "Download URL: : " . $file->getDownloadUrl();

        return $file;
    } catch (Exception $e) {
        print "An error occurred: " . $e->getMessage();
    }
}

/**
 * Download a file's content.
 *
 * @param Google_Service_Drive $service Drive API service instance.
 * @param Google_Service_Drive_DriveFile $file Drive File instance.
 * @return String The file's content if successful, null otherwise.
 */
function downloadFile($service, $file) {
    $downloadUrl = $file->getDownloadUrl();
    if ($downloadUrl) {
        $request = new Google_Http_Request($downloadUrl, 'GET', null, null);
        $httpRequest = $service->getClient()->getAuth()->authenticatedRequest($request);
        if ($httpRequest->getResponseHttpCode() == 200) {
            return $httpRequest->getResponseBody();
        } else {
            // An error occurred.
            return null;
        }
    } else {
        // The file doesn't have any content stored on Drive.
        return null;
    }
}

// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Drive($client);


$fileId = $_GET['id'];
$file = printFile($service, $fileId);
echo "<br/><pre>";
print_r($file);
echo "</pre><hr/>";
print_r(downloadFile($service, $file));

Here's the response of printFile() , as you can see, the fields that should contain links appear to be blank.

[0] => Google_Service_Drive_DriveFile Object
                        (
                            [collection_key:protected] => spaces
                            [appProperties] => 
                            [capabilitiesType:protected] => Google_Service_Drive_DriveFileCapabilities
                            [capabilitiesDataType:protected] => 
                            [contentHintsType:protected] => Google_Service_Drive_DriveFileContentHints
                            [contentHintsDataType:protected] => 
                            [createdTime] => 
                            [description] => 
                            [explicitlyTrashed] => 
                            [fileExtension] => 
                            [folderColorRgb] => 
                            [fullFileExtension] => 
                            [headRevisionId] => 
                            [iconLink] => 
                            [id] => XXXXXXX  //I've removed this, but it is a valid id, I've checked.
                            [imageMediaMetadataType:protected] => Google_Service_Drive_DriveFileImageMediaMetadata
                            [imageMediaMetadataDataType:protected] => 
                            [kind] => 
                            [lastModifyingUserType:protected] => Google_Service_Drive_User
                            [lastModifyingUserDataType:protected] => 
                            [md5Checksum] => 
                            [mimeType] => 
                            [modifiedByMeTime] => 
                            [modifiedTime] => 
                            [name] => blue_and_white_diagonal_stripes_background_seamless.gif
                            [originalFilename] => 
                            [ownedByMe] => 
                            [ownersType:protected] => Google_Service_Drive_User
                            [ownersDataType:protected] => array
                            [parents] => 
                            [permissionsType:protected] => Google_Service_Drive_Permission
                            [permissionsDataType:protected] => array
                            [properties] => 
                            [quotaBytesUsed] => 
                            [shared] => 
                            [sharedWithMeTime] => 
                            [sharingUserType:protected] => Google_Service_Drive_User
                            [sharingUserDataType:protected] => 
                            [size] => 
                            [spaces] => 
                            [starred] => 
                            [thumbnailLink] => 
                            [trashed] => 
                            [version] => 
                            [videoMediaMetadataType:protected] => Google_Service_Drive_DriveFileVideoMediaMetadata
                            [videoMediaMetadataDataType:protected] => 
                            [viewedByMe] => 
                            [viewedByMeTime] => 
                            [viewersCanCopyContent] => 
                            [webContentLink] => 
                            [webViewLink] => 
                            [writersCanShare] => 
                            [internal_gapi_mappings:protected] => Array
                                (
                                )

                            [modelData:protected] => Array
                                (
                                )

                            [processed:protected] => Array
                                (
                                )

                        )

I'm also unclear as to the difference between v2 and v3 of the API and may have muddled them up? They both seem to use the same quickstart.php code.

Thanks for any help!

For your question, what is the difference between Drive v2 and v3.

Here is some of the changes:

  • The getItems() method in v2 will become getFiles( ) in v3 and the getTitle() will become getName() .

  • Full resources are no longer returned by default. Use the fields query parameter to request specific fields to be returned. If left unspecified only a subset of commonly used fields are returned.

  • All update operations now use PATCH instead of PUT

  • The exportLinks field has been removed from files. To export Google Documents, use the files.export method instead.

For more information check this documentation .

For your problem in downloading files. Try to check this SO question .

According to this, in getting the downloadUrls you need to get the metadata of a file. You can do so by using the GET method. The method will return a File Resource representation. In this resource, there is a downloadUrl property. If you're able to access the files and get the URL already, then there should be no problem with your authentication setup. There could be permission issues where you may not have access to certain drive files.

You can also check this SO question for more information

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM