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.
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
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.
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 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 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.
<?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($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);
}
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($ch, CURLOPT_URL, $apiURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: '.$mime_type, 'Authorization: Bearer '. $access_token));
curl_setopt($ch, CURLOPT_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($ch, CURLOPT_URL, $apiURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 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, 'PATCH');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_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;
}
}
?>
In the config.php
file, database settings and Google API configuration constant variables are defined.
Database constants:
Google API constants:
https://www.googleapis.com/auth/drive
). 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.
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 select file for upload any type of files (.jpg, .jpeg, .png, .pdf, .xlsx, .csv, etc).
enctype
attribute must be defined in the <form> tag to allow file upload.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>
The upload.php
file handles the file upload in PHP and data insertion process to the MySQL database.
<?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();
?>
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.
GetAccessToken()
function of the GoogleDriveApi
class.UploadFileToDrive()
function of the GoogleDriveApi
class.UpdateFileMeta()
function of the GoogleDriveApi
class.<?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_ID, REDIRECT_URI, GOOGLE_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();
}
?>
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.
File Upload with Progress Bar using jQuery Ajax and PHP
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
This is a very good topic to learn about uploading files in Google Drive. I am trying to execute it for learning purposes. Thanks
If we want to upload any file in a particular folder of google drive, then tell its code.
See the code from here – https://www.codexqa.com/questions/232/how-to-upload-files-to-specific-folder-in-google-drive-using-php
How to create folder in google drive using php curl??
Hi, can you explain how can we manage this uploading functionality without the use of database and table. Also how to integrate this into Yii 2 framework
Can you tell how can I integrate your code in Yii2 basic application template
I am using Yii 2 basic application template. I am using google client api and installed it thorugh composer. Every time the code asks for the verfication code to enter through command prompt in my code for authorization. I dont want the user to start the command prompt and then enter the verification code. Any changes to make. Below is my code
hello, if I wanted to upload a file in a specific folder what should I change?
what if i want to delete a file or create a folder? can you do a tutorial? Thank you
It’s really nice, thanks !