使用PHP下载带有Google Drive API的文件

时间:2016-04-13 17:25:11

标签: php google-drive-api

我试图建立一个系统,让我可以让我的服务器与Google云端硬盘中充满照片的文件夹保持同步(单向)。

到目前为止,我已经设法从github下载PHP客户端库(我不使用作曲家)并列出一些文件。我设法使用以下方法手动获取其中一张照片的ID:

// 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>";
}

但是我无法从ID中下载文件,这是我尝试过的内容,但是我收到错误说明了 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));

以下是printFile()的回复,正如您所看到的,应包含链接的字段显示为空白。

[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
                                (
                                )

                        )

我还不清楚API的v2和v3之间的区别,可能混淆了它们吗?他们似乎都使用相同的quickstart.php代码。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

对于您的问题,Drive v2和v3之间有什么区别。

以下是一些变化:

  • v3中的getItems()方法将成为getFiles(),而getTitle()将成为getName()

  • 默认情况下不再返回完整资源。使用fields查询参数来请求返回特定字段。如果未指定,则仅返回常用字段的子集。

  • 所有更新操作现在都使用PATCH而不是PUT

  • 已从文件中删除了exportLinks字段。要导出Google文档,请改用files.export方法。

有关详细信息,请查看此documentation

有关下载文件的问题。请尝试检查此SO question

根据这一点,在获取downloadUrls时需要获取文件的元数据。您可以使用GET方法执行此操作。该方法将返回File Resource表示。在此资源中,存在downloadUrl属性。如果您能够访问这些文件并获取URL,那么您的身份验证设置应该没有问题。可能存在权限问题,您可能无法访问某些驱动器文件。

您还可以查看此SO question以获取更多信息