Download File from Google Drive using PHP

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.

  • Build an HTML form to allow users to input the ID of the Google Drive file.
  • Authenticate user with Google account.
  • Fetch file metadata and media content from Google Drive API.
  • Download file from PHP script using Google Drive API.
  • Store files on the local server and insert file info in the database.
  • Display file download status with details.

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

Create Google Project and Enable Drive API

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.

  • Go to the Google API Console.
  • Select an existing project from the projects list, or click NEW PROJECT to create a new project:
    google-api-console-project-create-codexworld
    • Type the Project Name.
    • The project ID will be created automatically under the Project Name field. (Optional) You can change this project ID by the Edit link, but it should be unique worldwide.
    • Click the CREATE button.
  • Select the newly created project and enable the Google Drive API service.
    • In the sidebar, select Library under the APIs & Services section.
    • Search for the Google Drive API service in the API list and select Google Drive API.
    • Click the ENABLE button to make the Google Drive API Library available.
  • In the sidebar, select Credentials under the APIs & Services section.
  • Select the OAuth consent screen tab, specify the consent screen settings.
    • Enter the Application name.
    • Choose a Support email.
    • Specify the Authorized domains which will be allowed to authenticate using OAuth.
    • Click the Save button.
  • Select the Credentials tab, click the Create credentials drop-down and select OAuth client ID.
    • In the Application type section, select Web application.
    • In the Authorized redirect URIs field, specify the redirect URL.
    • Click the Create button.

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.

google-api-console-project-oauth-api-key-client-id-secret-codexworld

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.

Create Database Table

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 Drive API Handler PHP Library

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.

  • GetAccessToken() – Fetch the access token from Google OAuth 2 API using the authentication code.
  • GetFileMeta() – Get file information (id, name, mime-type, etc.) from Drive API (Files:get) based on File ID using PHP.
  • GetFileMediaContent () – Fetch file contents from Drive API based on the fileId 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($chCURLOPT_URLself::OAUTH2_TOKEN_URI);        
        
curl_setopt($chCURLOPT_RETURNTRANSFER1);        
        
curl_setopt($chCURLOPT_POST1);        
        
curl_setopt($chCURLOPT_SSL_VERIFYPEERFALSE);
        
curl_setopt($chCURLOPT_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($chCURLOPT_URL$apiURL);
        
curl_setopt($chCURLOPT_RETURNTRANSFER1);
        
curl_setopt($chCURLOPT_SSL_VERIFYPEERFALSE); 
        
curl_setopt($chCURLOPT_HTTPHEADER, array('Content-Type: application/json''Authorization: Bearer '$access_token)); 
        
curl_setopt($chCURLOPT_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($chCURLOPT_URL$apiURL);
        
curl_setopt($chCURLOPT_RETURNTRANSFER1);
        
curl_setopt($chCURLOPT_SSL_VERIFYPEERFALSE); 
        
curl_setopt($chCURLOPT_HTTPHEADER, array('Content-Type: application/json''Authorization: Bearer '$access_token)); 
        
curl_setopt($chCURLOPT_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;
    }
}
?>

Database and API Configuration (config.php)

In the config.php file, database settings and Google API configuration constant variables are defined.

Download constants:

  • $target_folder – Specify the directory where the file will be stored after downloading from Google Drive.

Database constants:

  • DB_HOST – Specify the database host.
  • DB_USERNAME – Specify the database username.
  • DB_PASSWORD – Specify the database password.
  • DB_NAME – Specify the database name.

Google API constants:

  • GOOGLE_CLIENT_ID – Specify the Google Project Client ID.
  • GOOGLE_CLIENT_SECRET – Specify the Google Project Client Secret.
  • GOOGLE_OAUTH_SCOPE – Specify the OAuth scope for Google authentication (set to https://www.googleapis.com/auth/drive).
  • REDIRECT_URI – Specify the Callback URL.

Google OAuth URL:
This URL format is predefined and doesn’t require any changes.

  • $googleOauthURL – The URL that allows the user to authenticate with Google account.
<?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.

Database Connection (dbConfig.php)

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_HOSTDB_USERNAMEDB_PASSWORDDB_NAME);

// Check connection
if ($db->connect_error) {
    die(
"Connection failed: " $db->connect_error);
}

File ID Input Form (index.php)

Create an HTML form to allow the user to input the ID of the file stored in Google Drive.

  • On submission, the file ID is posted to the server-side script (google_drive_sync.php) for further processing.
<?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>

Download File from Google Drive (google_drive_sync.php)

The google_drive_sync.php file handles the file download process with Google Drive API using PHP.

  • Include and initialize the Google Drive API handler PHP library.
  • Get file ID from the input field using the PHP $_POST method.
  • Validate input to check whether mandatory fields are empty.
  • Store the given Google Drive file ID in SESSION.
  • Redirect user to the OAuth URL for authentication with Google account.

When the user redirects back after the authentication with their Google account.

  • Get OAuth code from the query string of the URL using the PHP $_GET method.
  • Get the file ID of the Google Drive from SESSION.
  • Get access token by authentication code using GetAccessToken() function of the GoogleDriveApi class.
  • Fetch file info (id, name, mime-type, etc) from Google Drive API using GetFileMeta() function of the GoogleDriveApi class.
  • Fetch and download file content from Google drive based on file ID using the GetFileMediaContent() function of the GoogleDriveApi class.
  • Save base64 encoded content as file on the server using file_put_contents() function in PHP.
  • Store file information in the database using PHP and MySQL.

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_IDREDIRECT_URIGOOGLE_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.

Downloaded File Details (details.php)

In this details.php file, the downloaded file details are displayed on the webpage.

  • The file information is fetched from the database based on the DB reference ID.
  • Display the file details with the Google Drive file view link.
<?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 ?>

Important Notes:

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-drive-file-share-link-permission-codexworld

Checklist for Testing:

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.

  • On the OAuth Client credentials page, click the OAuth consent screen link.
    google-api-console-oauth-client-credentials-codexworld
  • In the OAuth consent screen page, add users under the Test users section.
    google-api-console-oauth-consent-test-user-codexworld

Add Event to Google Calendar using PHP

Conclusion

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

5 Comments

  1. Hari Said...
  2. Ken Said...
  3. تبدیل لینک خارجی به داخلی نیم بها Said...
  4. Dh7382 Said...
  5. John Dew Said...

Leave a reply

keyboard_double_arrow_up