Drive API provides a quick and secure way to manage files in Google Drive programmatically. This REST API service allows to upload, download, and manage files in Google Drive from the website remotely. The cURL is very useful to make REST API call with HTTP requests in PHP and it can be used to call the Drive API from the PHP script. We have already shared a tutorial to upload files to Google Drive with Drive API using PHP. In this tutorial, we will explain how to download files from Google Drive using PHP.
In this example script, we will implement the following functionality to download files from Google Drive with PHP.
Before getting started to build a PHP script to download files from Google drive using PHP, take a look at the file structure.
google_drive_file_download_with_php/ ├── config.php ├── dbConfig.php ├── index.php ├── details.php ├── google_drive_sync.php ├── GoogleDriveApi.class.php └── css/ └── style.css
The Client ID and Client Secret are required to make API calls to Google Drive. If you already have an existing project at the Google API console, create OAuth Client IDs from there. But you have to make sure that Google Drive API is enabled in this existing Google API console application.
If you don’t have any application at the Google API console, follow the below steps to register your application and create OAuth Client IDs on Google Developers Console.
A dialog box will appear with OAuth client details, note the Client ID and Client secret for later use in the script. This Client ID and Client secret allow you to access the Google Drive API.
Note that: The Client ID and Client secret need to be specified at the time of the Google Drive API call. Also, the Authorized redirect URIs must be matched with the Redirect URL specified in the script.
A table is required in the database to store downloaded file information on the local server. The following SQL creates a drive_files
table with some basic fields in the MySQL database.
CREATE TABLE `drive_files` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`google_drive_file_id` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`file_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`mime_type` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`created` datetime NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Google provides a PHP client library to make Drive API calls, but it contains many additional services that come with a huge number of files and are large in size. To make the process simple, we will build a custom library to handle the Google Drive API calls with PHP.
This Google API class helps to authenticate with a Google account and access the Drive API with REST API using PHP cURL. This custom PHP library will use Google Drive API v3 to handle the file download process.
Files:get
) based on File ID using PHP.<?php
/**
*
* This Google Drive API handler class is a custom PHP library to handle the Google Drive API calls.
*
* @class GoogleDriveApi
* @author CodexWorld
* @link http://www.codexworld.com
* @version 1.0
*/
class GoogleDriveApi {
const OAUTH2_TOKEN_URI = 'https://oauth2.googleapis.com/token';
const DRIVE_FILE_META_URI = 'https://www.googleapis.com/drive/v3/files/';
function __construct($params = array()) {
if (count($params) > 0){
$this->initialize($params);
}
}
function initialize($params = array()) {
if (count($params) > 0){
foreach ($params as $key => $val){
if (isset($this->$key)){
$this->$key = $val;
}
}
}
}
public function GetAccessToken($client_id, $redirect_uri, $client_secret, $code) {
$curlPost = 'client_id=' . $client_id . '&redirect_uri=' . $redirect_uri . '&client_secret=' . $client_secret . '&code='. $code . '&grant_type=authorization_code';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, self::OAUTH2_TOKEN_URI);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$data = json_decode(curl_exec($ch), true);
$http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
if ($http_code != 200) {
$error_msg = 'Failed to receieve access token';
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
}else{
$error_msg = !empty($data['error']['message'])?$data['error']['message']:'';
}
throw new Exception('Error '.$http_code.': '.$error_msg);
}
return $data;
}
public function GetFileMeta($access_token, $file_id, $googleOauthURL = '') {
$apiURL = self::DRIVE_FILE_META_URI . $file_id;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Authorization: Bearer '. $access_token));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$data = json_decode(curl_exec($ch), true);
$http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
if ($http_code != 200) {
$error_msg = 'Failed to retrieve file metadata';
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
}else{
$error_msg = !empty($data['error']['message'])?$data['error']['message']:'';
}
if($http_code == 401 && !empty($googleOauthURL)){
unset($_SESSION['google_access_token']);
$error_msg .= '<br/>Click to <a href="'.$googleOauthURL.'">authenticate with Google Drive</a>';
}
throw new Exception('Error '.$http_code.': '.$error_msg);
}
return $data;
}
public function GetFileMediaContent($access_token, $file_id, $googleOauthURL = '') {
$apiURL = self::DRIVE_FILE_META_URI . $file_id . '?alt=media';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Authorization: Bearer '. $access_token));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
//$data = json_decode(curl_exec($ch), true);
$data = curl_exec($ch);
$http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
if ($http_code != 200) {
$error_msg = 'Failed to retrieve file data';
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
}else{
$error_msg = !empty($data['error']['message'])?$data['error']['message']:'';
}
if($http_code == 401 && !empty($googleOauthURL)){
unset($_SESSION['google_access_token']);
$error_msg .= '<br/>Click to <a href="'.$googleOauthURL.'">authenticate with Google Drive</a>';
}
throw new Exception('Error '.$http_code.': '.$error_msg);
}
return $data;
}
}
?>
In the config.php
file, database settings and Google API configuration constant variables are defined.
Download constants:
Database constants:
Google API constants:
https://www.googleapis.com/auth/drive
).Google OAuth URL:
This URL format is predefined and doesn’t require any changes.
<?php
// Folder to store files
$target_folder = 'drive_files';
// Database configuration
define('DB_HOST', 'MySQL_Database_Host');
define('DB_USERNAME', 'MySQL_Database_Username');
define('DB_PASSWORD', 'MySQL_Database_Password');
define('DB_NAME', 'MySQL_Database_Name');
// Google API configuration
define('GOOGLE_CLIENT_ID', 'Google_Project_Client_ID');
define('GOOGLE_CLIENT_SECRET', 'Google_Project_Client_Secret');
define('GOOGLE_OAUTH_SCOPE', 'https://www.googleapis.com/auth/drive');
define('REDIRECT_URI', 'https://www.example.com/google_drive_sync.php');
// Start session
if(!session_id()) session_start();
// Google OAuth URL
$googleOauthURL = 'https://accounts.google.com/o/oauth2/auth?scope=' . urlencode(GOOGLE_OAUTH_SCOPE) . '&redirect_uri=' . REDIRECT_URI . '&response_type=code&client_id=' . GOOGLE_CLIENT_ID . '&access_type=online';
?>
Note that: The Client ID and Client Secret can be found on the Google API Manager page of the API Console project.
The dbConfig.php
file is used to connect and select the MySQL database using PHP.
<?php
// Include configuration file
require_once 'config.php';
// Create database connection
$db = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME);
// Check connection
if ($db->connect_error) {
die("Connection failed: " . $db->connect_error);
}
Create an HTML form to allow the user to input the ID of the file stored in Google Drive.
<?php
// Include configuration file
include_once 'config.php';
$status = $statusMsg = '';
if(!empty($_SESSION['status_response'])){
$status_response = $_SESSION['status_response'];
$status = $status_response['status'];
$statusMsg = $status_response['status_msg'];
unset($_SESSION['status_response']);
}
?>
<!-- Status message -->
<?php if(!empty($statusMsg)){ ?>
<div class="alert alert-<?php echo $status; ?>"><?php echo $statusMsg; ?></div>
<?php } ?>
<div class="col-md-12">
<form method="post" action="google_drive_sync.php" class="form">
<div class="form-group">
<label>Drive File ID:</label>
<input type="text" name="file_id" class="form-control" placeholder="Enter ID of Google Drive file">
</div>
<div class="form-group">
<input type="submit" class="form-control btn-primary" name="submit" value="Download"/>
</div>
</form>
</div>
The google_drive_sync.php
file handles the file download process with Google Drive API using PHP.
When the user redirects back after the authentication with their Google account.
GetAccessToken()
function of the GoogleDriveApi class.GetFileMeta()
function of the GoogleDriveApi class.GetFileMediaContent()
function of the GoogleDriveApi class.Redirect to the details page to display the status message with downloaded file information.
<?php
// Include and initialize Google Drive API handler class
include_once 'GoogleDriveApi.class.php';
$GoogleDriveApi = new GoogleDriveApi();
// Include database configuration file
require_once 'dbConfig.php';
$statusMsg = $valErr = $access_token = '';
$status = 'danger';
$redirectURL = 'index.php';
// If the form is submitted
if(isset($_POST['submit'])){
// Validate form input fields
if(empty($_POST["file_id"])){
$valErr .= 'Please enter ID of Google Drive file.';
}
// Check whether user inputs are empty
if(empty($valErr)){
$drive_file_id = $_POST["file_id"];
// Store reference ID of file in SESSION
$_SESSION['last_file_id'] = $drive_file_id;
// Get the access token
if(!empty($_SESSION['google_access_token'])){
$access_token = $_SESSION['google_access_token'];
}else{
// Redirect to the Google authentication site
header("Location: $googleOauthURL");
exit();
}
}else{
$statusMsg = '<p>Please fill all the mandatory fields:</p>'.trim($valErr, '<br/>');
}
}elseif(isset($_GET['code'])){
// Get file reference ID from SESSION
$drive_file_id = $_SESSION['last_file_id'];
if(!empty($drive_file_id)){
// Get the access token
if(!empty($_SESSION['google_access_token'])){
$access_token = $_SESSION['google_access_token'];
}else{
$data = $GoogleDriveApi->GetAccessToken(GOOGLE_CLIENT_ID, REDIRECT_URI, GOOGLE_CLIENT_SECRET, $_GET['code']);
$access_token = $data['access_token'];
$_SESSION['google_access_token'] = $access_token;
}
}else{
$statusMsg = 'File reference not found!';
}
}else{
$statusMsg = 'Unauthorized access!';
}
if(!empty($access_token)){
// Fetch file metadata from Google drive
try {
$drive_file_data = $GoogleDriveApi->GetFileMeta($access_token, $drive_file_id, $googleOauthURL);
} catch(Exception $e) {
$api_error = $e->getMessage();
}
if(!empty($drive_file_data) && empty($api_error)){
// File information
$drive_file_id = $drive_file_data['id'];
$drive_file_name = $drive_file_data['name'];
$drive_file_mime_type = $drive_file_data['mimeType'];
// File save path
$target_file = $target_folder.'/'.$drive_file_data['name'];
// Fetch file content from Google drive
try {
$drive_file_content = $GoogleDriveApi->GetFileMediaContent($access_token, $drive_file_id, $googleOauthURL);
} catch(Exception $e) {
$api_error = $e->getMessage();
}
if(!empty($drive_file_content) && empty($api_error)){
// Save base64 encoded content as file on the server
file_put_contents($target_file, $drive_file_content);
// Insert file info in the database
$sqlQ = "INSERT INTO drive_files (google_drive_file_id, file_name, mime_type, created) VALUES (?,?,?,NOW())";
$stmt = $db->prepare($sqlQ);
$stmt->bind_param("sss", $db_drive_file_id, $db_drive_file_name, $db_drive_file_mime_type);
$db_drive_file_id = $drive_file_id;
$db_drive_file_name = $drive_file_name;
$db_drive_file_mime_type = $drive_file_mime_type;
$insert = $stmt->execute();
if($insert){
$file_id = $stmt->insert_id;
}
$status = 'success';
$statusMsg = 'The file is downloaded from Google Drive and saved on the server successfully!';
$redirectURL = 'details.php?fid='.$file_id;
unset($_SESSION['last_file_id']);
}else{
$statusMsg = 'File not found : '.$api_error;
}
}else{
$statusMsg = 'File metadata not found : '.$api_error;
}
}else{
unset($_SESSION['google_access_token']);
$statusMsg = !empty($statusMsg)?$statusMsg:'Failed to fetch access token! Click to <a href="'.$googleOauthURL.'">authenticate with Google Drive</a>';
}
$_SESSION['status_response'] = array('status' => $status, 'status_msg' => $statusMsg);
header("Location: $redirectURL");
exit();
?>
Note that: This file URL must be set as Redirect URL in Authorized redirect URIs section of the Google API console project.
In this details.php
file, the downloaded file details are displayed on the webpage.
<?php
// Include configuration file
include_once 'dbConfig.php';
if(!empty($_GET['fid'])){
// Fetch file details from the database
$sqlQ = "SELECT * FROM drive_files WHERE id = ?";
$stmt = $db->prepare($sqlQ);
$stmt->bind_param("i", $db_file_id);
$db_file_id = $_GET['fid'];
$stmt->execute();
$result = $stmt->get_result();
$fileData = $result->fetch_assoc();
if(!empty($fileData)){
$google_drive_file_id = $fileData['google_drive_file_id'];
$file_name = $fileData['file_name'];
$mime_type = $fileData['mime_type'];
$file_path_server = $target_folder.'/'.$file_name;
$file_path_drive = 'https://drive.google.com/open?id='.$google_drive_file_id;
}
}else{
header("Location: index.php");
exit();
}
$status = $statusMsg = '';
if(!empty($_SESSION['status_response'])){
$status_response = $_SESSION['status_response'];
$status = $status_response['status'];
$statusMsg = $status_response['status_msg'];
unset($_SESSION['status_response']);
}
?>
<!-- Status message -->
<?php if(!empty($statusMsg)){ ?>
<div class="alert alert-<?php echo $status; ?>"><?php echo $statusMsg; ?></div>
<?php } ?>
<?php if(!empty($fileData)){ ?>
<div class="card">
<div class="card-body">
<p class="card-text"><b>File Name:</b> <?php echo $file_name; ?></p>
<p class="card-text"><b>File ID:</b> <?php echo $google_drive_file_id; ?></p>
<p class="card-text"><b>Mime Type:</b> <?php echo $mime_type; ?></p>
<p><b>Google Drive File URL:</b> <a href="<?php echo $file_path_drive; ?>" target="_blank"><?php echo $file_path_drive; ?></a></p>
</div>
<a href="index.php" class="btn btn-primary">Back to Home</a>
</div>
<?php } ?>
If you want to download the file from Google Drive other than the authenticated Google account, make sure the file sharing option is set to Anyone with the link.
Google Application Verification:
Google requires application verification to use Drive API. You need to submit the application for verification to make Google project public.
In the development mode, you can test it by adding Test Users in the OAuth consent screen of the Google application.
Add Event to Google Calendar using PHP
Downloading files from Google drive with REST API is a simple way to get images or files from Google Drive dynamically. You can download Google Drive files and save them on the local server with Drive API using PHP. In this sample application, the access token is stored in SESSION which helps to get files from Google Drive without authentication with Google account.
Do you want to get implementation help, or enhance the functionality of this script? Click here to Submit Service Request
Need implementation guidence
awesome, can you guide how to make gallery page from google driver shared folder? Just copy the link from the google drive shared folder and paste it in the input box and then press save, the image display page will list all the images in that driver link?
very good bro.thx for sharing
how can we bypass download limit with google api .imea we have 2 same file in different drives and when limit reach in first drive .then we use the api to download from second drive automatically.
Great job bro !
Work like a charm! Thanks for this script.