Upload File to Google Drive using PHP

Google Drive is a cloud storage engine that allows users to store and share files efficiently. The files are synchronized across devices and can be accessed from anywhere. Google drive makes document management easy without any personal storage. You can also manage files and folders in Google drive remotely using Drive API.

The Drive API allows managing files and folders stored on Google Drive. You can upload and manage files from the website using Google Drive API. If the web application requires to allow users to access or manage Google drive files, Drive API provides a simple way to upload files to Google drive programmatically with REST API service. This tutorial explains how to upload file to Google Drive using PHP.

In this example PHP script, the following process will be implemented to upload files to Google Drive with PHP.

  • Build an HTML form to select file to upload.
  • Upload file to the local server and insert file info in the database.
  • Authenticate user with Google account.
  • Upload file to Google Drive from the PHP script.
  • Display file upload status with a link to view file on Google drive.

Before getting started to build a PHP script to upload file to Google drive using PHP, take a look at the file structure.

google_drive_file_upload_with_php/
├── config.php
├── dbConfig.php
├── index.php
├── upload.php
├── google_drive_sync.php
├── GoogleDriveApi.class.php
└── css/
    └── style.css

Create Google Project and Enable Drive API

Google Project is required to get the API keys that will be used to make API calls to Google Drive. If you already have an existing Google Application, API keys can be used from it. Just make sure that the Google Drive API is enabled in this existing Google project. If you don’t any Google applications, follow the below steps to register your application on Google Developers Console and get the API keys.

  • 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 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,
  `file_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `google_drive_file_id` varchar(255) 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 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.

Our Google API Library helps to authenticate with Google account and access the Drive API with REST API using PHP cURL. This custom PHP library will use Google Drive v3 API to handle the file upload process.

  • GetAccessToken() – Fetch the access token from Google OAuth 2 API using authentication code.
  • UploadFileToDrive() – Send file to Google Drive for upload using REST API.
  • UpdateFileMeta() – Update metadata of the uploaded file in Google Drive.
<?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_UPLOAD_URI 'https://www.googleapis.com/upload/drive/v3/files';
    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);
            }
            throw new 
Exception('Error '.$http_code.': '.$error_msg);
        }
            
        return 
$data;
    }
    
    public function 
UploadFileToDrive($access_token$file_content$mime_type) {
        
$apiURL self::DRIVE_FILE_UPLOAD_URI '?uploadType=media';
        
        
$ch curl_init();        
        
curl_setopt($chCURLOPT_URL$apiURL);        
        
curl_setopt($chCURLOPT_RETURNTRANSFER1);        
        
curl_setopt($chCURLOPT_POST1);        
        
curl_setopt($chCURLOPT_SSL_VERIFYPEERFALSE);
        
curl_setopt($chCURLOPT_HTTPHEADER, array('Content-Type: '.$mime_type'Authorization: Bearer '$access_token));
        
curl_setopt($chCURLOPT_POSTFIELDS$file_content);
        
$data json_decode(curl_exec($ch), true);
        
$http_code curl_getinfo($ch,CURLINFO_HTTP_CODE);        
        
        if (
$http_code != 200) {
            
$error_msg 'Failed to upload file to Google Drive';
            if (
curl_errno($ch)) {
                
$error_msg curl_error($ch);
            }
            throw new 
Exception('Error '.$http_code.': '.$error_msg);
        }

        return 
$data['id'];
    }
    
    public function 
UpdateFileMeta($access_token$file_id$file_meatadata) {
        
$apiURL self::DRIVE_FILE_META_URI $file_id;
        
        
$ch curl_init();        
        
curl_setopt($chCURLOPT_URL$apiURL);        
        
curl_setopt($chCURLOPT_RETURNTRANSFER1);        
        
curl_setopt($chCURLOPT_POST1);        
        
curl_setopt($chCURLOPT_SSL_VERIFYPEERFALSE);
        
curl_setopt($chCURLOPT_HTTPHEADER, array('Content-Type: application/json''Authorization: Bearer '$access_token));
        
curl_setopt($chCURLOPT_CUSTOMREQUEST'PATCH');
        
curl_setopt($chCURLOPT_POSTFIELDSjson_encode($file_meatadata));
        
$data json_decode(curl_exec($ch), true);
        
$http_code curl_getinfo($ch,CURLINFO_HTTP_CODE);        
        
        if (
$http_code != 200) {
            
$error_msg 'Failed to update file metadata';
            if (
curl_errno($ch)) {
                
$error_msg curl_error($ch);
            }
            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.

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:

  • $googleOauthURL – The URL that allows the user to authenticate with Google account.
<?php 
// 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 Upload Form (index.php)

Create an HTML form to select file for upload any type of files (.jpg, .jpeg, .png, .pdf, .xlsx, .csv, etc).

  • The enctype attribute must be defined in the <form> tag to allow file upload.
  • On submission, the file data is posted to the server-side script (upload.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="upload.php" class="form" enctype="multipart/form-data"> <div class="form-group"> <label>File</label> <input type="file" name="file" class="form-control"> </div> <div class="form-group"> <input type="submit" class="form-control btn-primary" name="submit" value="Upload"/> </div> </form> </div>

Store File in the Database (upload.php)

The upload.php file handles the file upload in PHP and data insertion process to the MySQL database.

  • Get file info from the input field using PHP $_FILES variable.
  • Validate input to check whether mandatory fields are empty.
  • Upload file to the local server and insert file data in the database using PHP and MySQL.
  • Redirect user to the OAuth URL for authentication with Google account.
<?php     
// Include database configuration file
require_once 'dbConfig.php';

$statusMsg $valErr '';
$status 'danger';

// If the form is submitted
if(isset($_POST['submit'])){
    
    
// Validate form input fields
    
if(empty($_FILES["file"]["name"])){
        
$valErr .= 'Please select a file to upload.<br/>';
    }
    
    
// Check whether user inputs are empty
    
if(empty($valErr)){
        
$targetDir "uploads/";
        
$fileName basename($_FILES["file"]["name"]);
        
$targetFilePath $targetDir $fileName;
        
        
// Upload file to local server
        
if(move_uploaded_file($_FILES["file"]["tmp_name"], $targetFilePath)){
            
            
// Insert data into the database
            
$sqlQ "INSERT INTO drive_files (file_name,created) VALUES (?,NOW())";
            
$stmt $db->prepare($sqlQ);
            
$stmt->bind_param("s"$db_file_name);
            
$db_file_name $fileName;
            
$insert $stmt->execute();
            
            if(
$insert){
                
$file_id $stmt->insert_id;
                
                
// Store DB reference ID of file in SESSION
                
$_SESSION['last_file_id'] = $file_id;
                
                
header("Location: $googleOauthURL");
                exit();
            }else{
                
$statusMsg 'Something went wrong, please try again after some time.';
            }
        }else{
            
$statusMsg 'File upload failed, please try again after some time.';
        }
    }else{
        
$statusMsg '<p>Please fill all the mandatory fields:</p>'.trim($valErr'<br/>');
    }
}else{
    
$statusMsg 'Form submission failed!';
}

$_SESSION['status_response'] = array('status' => $status'status_msg' => $statusMsg);

header("Location: index.php");
exit();
?>

Upload File to Google Drive (google_drive_sync.php)

This script is set as Redirect URI in Google API configuration. This means after authentication with Google account, the user will be redirected to this script that handles the Google Drive file upload process with REST API using PHP.

  • Get OAuth code from the query string of the URL using PHP $_GET variable.
  • Include and initialize the Google Drive API handler class.
  • Get file reference ID of the local database from SESSION.
  • Fetch the file info from the database based on the reference ID.
  • Retrieve file from the server and define entire file into a string using file_get_contents() function in PHP.
  • Get MIME type of the file using mime_content_type() function in PHP.
  • Get access token by authentication code using GetAccessToken() function of the GoogleDriveApi class.
  • Send and upload file to Google Drive using UploadFileToDrive() function of the GoogleDriveApi class.
  • Update file meta data in Google Drive using the UpdateFileMeta() function of the GoogleDriveApi class.
  • Update google drive file reference ID in the database.
  • Display file upload status with Google drive file access link.
<?php 
// Include Google drive api handler class
include_once 'GoogleDriveApi.class.php';
    
// Include database configuration file
require_once 'dbConfig.php';

$statusMsg '';
$status 'danger';
if(isset(
$_GET['code'])){
    
// Initialize Google Drive API class
    
$GoogleDriveApi = new GoogleDriveApi();
    
    
// Get file reference ID from SESSION
    
$file_id $_SESSION['last_file_id'];

    if(!empty(
$file_id)){
        
        
// 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 $file_id;
        
$stmt->execute();
        
$result $stmt->get_result();
        
$fileData $result->fetch_assoc();
        
        if(!empty(
$fileData)){
            
$file_name $fileData['file_name'];
            
$target_file 'uploads/'.$file_name;
            
$file_content file_get_contents($target_file);
            
$mime_type mime_content_type($target_file);
            
            
// 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;
            }
            
            if(!empty(
$access_token)){
                
                try {
                    
// Upload file to Google drive
                    
$drive_file_id $GoogleDriveApi->UploadFileToDrive($access_token$file_content$mime_type);
                    
                    if(
$drive_file_id){
                        
$file_meta = array(
                            
'name' => basename($file_name)
                        );
                        
                        
// Update file metadata in Google drive
                        
$drive_file_meta $GoogleDriveApi->UpdateFileMeta($access_token$drive_file_id$file_meta);
                        
                        if(
$drive_file_meta){
                            
// Update google drive file reference in the database
                            
$sqlQ "UPDATE drive_files SET google_drive_file_id=? WHERE id=?";
                            
$stmt $db->prepare($sqlQ);
                            
$stmt->bind_param("si"$db_drive_file_id$db_file_id);
                            
$db_drive_file_id $drive_file_id;
                            
$db_file_id $file_id;
                            
$update $stmt->execute();
                            
                            unset(
$_SESSION['last_file_id']);
                            unset(
$_SESSION['google_access_token']);
                            
                            
$status 'success';
                            
$statusMsg '<p>File has been uploaded to Google Drive successfully!</p>';
                            
$statusMsg .= '<p><a href="https://drive.google.com/open?id='.$drive_file_meta['id'].'" target="_blank">'.$drive_file_meta['name'].'</a>';
                        }
                    }
                } catch(
Exception $e) {
                    
$statusMsg $e->getMessage();
                }
            }else{
                
$statusMsg 'Failed to fetch access token!';
            }
        }else{
            
$statusMsg 'File data not found!';
        }
    }else{
        
$statusMsg 'File reference not found!';
    }
    
    
$_SESSION['status_response'] = array('status' => $status'status_msg' => $statusMsg);
    
    
header("Location: index.php");
    exit();
}
?>

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

File Upload with Progress Bar using jQuery Ajax and PHP

Conclusion

Upload files to Google drive with REST API is very useful when you want to upload images or document files to Google drive dynamically from the website. The PHP cURL functions help to call REST API to access Google Drive API from the script. Not only file upload but also you can create folders, view/update/delete files using Google Drive API and PHP. If you want to save scape on the server, files can be uploaded to Google drive and reference can be used to access files from Google Drive.

Do you want to get implementation help, or enhance the functionality of this script? Click here to Submit Service Request

9 Comments

  1. Sundar Sau Said...
  2. Ramanath Mahato Said...
  3. Shahnam Said...
  4. Prashant Said...
  5. Prashant Said...
  6. Prashant Said...
  7. Onofrio Said...
  8. Don Said...

Leave a reply

keyboard_double_arrow_up