Я пытаюсь загрузить файл с общего диска через API Google. Всегда получаю ответ, что файл не найден (код 404).
Это не работает, даже если у меня есть полный доступ (администратор) к папке. Файлы созданы мной. Если я сохранил их в «Мою папку», это работает без проблем.
Я использую конечную точку экспорта для собственных файлов Google для экспорта в формате PDF: https://developers.google.com/drive/api/reference/rest/v3/files/export
А для всех остальных файлов я использую конечную точку get: https://developers.google.com/drive/api/reference/rest/v3/files/get
Я работаю с PHP-клиентом Google API (v2.15.3): https://github.com/googleapis/google-api-php-client/
API Google Диска активируется в консоли Google. Также настраивается идентификатор клиента OAuth 2.0 для веб-приложений. Со всеми правами, доступными через Google Drive API.
Как я могу получить файлы с общего диска?
Вот код, в котором я пытаюсь получить файл:
<?php
require_once __DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
$client = new Google_Client();
# Todo: need to change
$client->setAuthConfig( __DIR__ . DIRECTORY_SEPARATOR . 'client_secret.json' );
$client->addScope( Google_Service_Drive::DRIVE );
$client->setAccessType( 'offline' );
$protocol = ( ! empty( $_SERVER[ 'HTTPS' ] ) && $_SERVER[ 'HTTPS' ] !== 'off' || $_SERVER[ 'SERVER_PORT' ] == 443 ) ? "https://" : "http://";
$currentUrl = $protocol . $_SERVER[ 'HTTP_HOST' ] . $_SERVER[ 'PHP_SELF' ];
$client->setRedirectUri( $currentUrl );
if ( ! isset( $_GET[ 'code' ] ) ) {
$auth_url = $client->createAuthUrl();
header( 'Location: ' . filter_var( $auth_url, FILTER_SANITIZE_URL ) );
exit;
}
else {
var_dump( $_GET[ 'code' ] );
var_dump( $client->fetchAccessTokenWithAuthCode( $_GET[ 'code' ] ) );
$_SESSION[ 'access_token' ] = $client->getAccessToken();
$driveService = new Google_Service_Drive( $client );
# Todo: need to change
$google_file_id = 'YOUR_FILE_ID_HERE';
try {
$file_metadata = $driveService->files->get( $google_file_id );
$response = $driveService->files->get( $google_file_id, array( 'alt' => 'media' ) );
$content = $response->getBody()->getContents();
if ( $file_metadata->getMimeType() && str_starts_with( $file_metadata->getMimeType(), 'application/vnd.google-apps.' ) ) {
$response = $driveService->files->export( $google_file_id, 'application/pdf', [ 'alt' => 'media' ] );
$file_name = $file_metadata->getName() . '.pdf';
}
else {
$response = $driveService->files->get( $google_file_id, [ 'alt' => 'media', 'supportsAllDrives' => true ] );
$file_name = $file_metadata->getName();
}
file_put_contents( __DIR__ . DIRECTORY_SEPARATOR . $file_name, $content );
echo "Stored!";
}
catch ( Exception $e ) {
echo '<pre>';
var_export( $e );
echo '</pre>';
}
}






Я думаю, что в вашем сценарии supportsAllDrives необходимо использовать для получения метаданных файла и содержимого файла с помощью files->get. А как насчет следующей модификации?
$client->setAccessToken( $access_token );
$driveService = new Google_Service_Drive( $client );
$file_metadata = $driveService->files->get( $google_file_id, ['fields' => "name,mimeType", "supportsAllDrives" => true] ); // or ['fields' => "*", "supportsAllDrives" => true]
if ( $file_metadata->getMimeType() && str_starts_with( $file_metadata->getMimeType(), 'application/vnd.google-apps.' ) ) {
$response = $driveService->files->export( $google_file_id, 'application/pdf');
$file_path = $routine_path . $file_metadata->getName() . '.pdf';
}
else {
$response = $driveService->files->get( $google_file_id, [ 'alt' => 'media', "supportsAllDrives" => true ] );
$file_path = $routine_path . $file_metadata->getName();
}
$content = $response->getBody()->getContents();
if ( file_put_contents( $file_path, $content ) ) {
$file_paths[] = $file_path;
}
@aswiss Спасибо за ответ. По поводу I've added your suggested modification. but without success ... I still get an exception with the 404 code., прошу прощения за неудобства. К сожалению, когда я протестировал предложенный сценарий, ошибок не произошло. Приношу извинения за эту ситуацию. Думаю, что в данном случае необходимо повторить вашу ситуацию. Итак, можете ли вы предоставить весь сценарий, отражающий предложенную мной модификацию, без вашей личной информации? Этим я хотел бы это подтвердить.
Спасибо за вашу поддержку. Я обновил свой вопрос и предоставил весь код.
@aswiss Спасибо за ответ. Я сказал can you provide your whole script reflecting my proposed modification without your private information?. Мне хотелось бы верить, что ваш обновленный вопрос отражает мой комментарий. Что касается Thanks for your support. I have updated my question and provide the entire code., когда я увидел ваш обновленный вопрос, я подумал, что, к сожалению, вы не отражаете предложенные мной изменения. Я думаю, что это связано с вашей текущей проблемой. Можете ли вы поразмышлять над предложенными мной модификациями и протестировать их?
@aswiss Когда я снова протестировал предложенный сценарий, я подтвердил, что сценарий снова работает для общего диска. Приношу извинения за эту ситуацию.
Вы правы, извините! Я скопировал код всех классов, чтобы сделать его доступным для совместного использования. Я не видел «supportsAllDrives» для конечной точки file.get в условии else. Теперь это работает. Спасибо!
Мне пришлось добавить опцию. параметры в эндоинт file.export ([ 'alt' => 'media' ]) ... В противном случае $content будет пустым.
Я добавил предложенную вами модификацию. но безуспешно... Я все равно получаю исключение с кодом 404.