Upload Files to Google Drive in PHP

Google Drive is a storage service google provides to every account with 15GB of free storage per drive. This drive is used to store different types of files. Learn in this post how to upload files to google drive from PHP application.

Upload Files to Google Drive in PHP

Besides 15GB free storage, it is possible to get extra storage by paying some fee every month. It is possible to upload to files to google drive from a web application using service account credentials. In this post we are going to learn how to upload multiple files to google drive in PHP using a service account. Files we are going to create for this post:

  1. index.php: The HTML page with file upload form.
  2. google-drive-file-upload.php: The server-side script code to upload files to google drive.
  3. style.css: The CSS stylesheet for HTML page.
 

How to Upload Files to Google Drive using PHP API

Uploading files to google drive involves some basic and simple steps like an interface to upload files, installing and using google API client library, and processing file uploads on server-side.We are going to create an HTML form with file upload field allow it to upload multiple files. We will use google API client library for PHP. Follow these steps to implement file upload to google drive in PHP using an API client library.

 

Step 1: Install Google API Client PHP Library

First we need google client API library to handle file uploads. We are going to use a PHP library for google API requests. Either install it via composer or download a zip file.

composer require google/apiclient:^2.15.0
 

Step 2: Create a Project in Cloud Console

We also need a project configured in google cloud console that will allow us to securely access google drive API from from a PHP application. To create a project in cloud console, go to Google Cloud Console and create a new project or use existing one. 

  • Click on "New Project" or select existing one from projects list.
  • Enter a project name in form field and click create.
Create Google Cloud Console Project

Step 3: Create a Service Account and Download Credentials

In order to securely access the google drive API, we need some credentials that will authenticate our API requests with google. Follow the steps to create a google service account and generate credentials keys.

  • From left navigation menu click "IAM and admin".
  • Click on "Service accounts" in sub menu.
  • Click on "+ Create service account".
  • Enter a service account name and description if needed.
  • Click on "Done".
  • Click "Keys" tab on the create service account's detail page.
  • Click on "Add key" and select "JSON" for Key type.
  • Click on "Create" and it will download a JSON key file. Place it in application's project directory.
Create Service Account and Download Credentials
 

Step 4: Create a Drive Folder and Share it with Service Account

We also need a directory or folder in google drive where we will store our uploaded files. Create a folder in google drive and share it with email address of google service account we just created. Go to your Google Drive and follow these steps: 

  • Click on "My Drive" and then click on "+ New" on top of left side menu.
  • From dropdown select "Folder" and enter a name for folder.
  • Click on "Create" and it will create a new folder in google drive.
  • Right click on folder you just create and click "+ Share".
  • In the input field enter the email address of service account we created in previous step.
  • Click on "Done".
 

Step 5: Create HTML Form to Upload Files to Google Drive

Now after google side configurations completed, we need a user interface in web application from where files can be uploaded to google drive. Create an index PHP file containing an HTML from with input file field to upload files to google drive from website:

  • Add the attribute enctype="multipart/form-data" to allow file uploads.
  • Add attribute multiple to file input field to allow selection of multiple files at once.
  • Add a container above form for success message when user redirects to this page after successful upload.
  • Add a container above form for error messages to display after user has been redirected to this page from server-side script.

index.php

<?php
if (!session_id()) {
session_start();
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Upload Files to Google Drive in PHP - Demo</title>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
<meta content="width=device-width, initial-scale=1, maximum-scale=1" name="viewport"/>
<link rel="stylesheet" href="css/style.css"/>
</head>
<body>
<section class="section py-4">
<div class="container">
<?php if (!empty($_SESSION['upload_errors'])) { ?>
<div class="alert alert-red">
<ul class="errors-list">
<?php foreach ($_SESSION['upload_errors'] as $file_error) { ?>
<li>
<strong><?= $file_error['file_name']; ?></strong>: <?= $file_error['message']; ?>
</li>
<?php } ?>
</ul>
</div>
<?php unset($_SESSION['upload_errors']); ?>
<?php } ?>

<?php if (!empty($_SESSION['success'])) { ?>
<div class="alert alert-green">
File(s) Successfully uploaded.
</div>
<?php unset($_SESSION['success']); ?>
<?php } ?>

<div class="mb-4">
<form action="google-drive-file-upload.php" method="POST" enctype="multipart/form-data"
class="google-drive-form">
<div class="mb-4">
<label class="inline-block mb-1">Attach files</label>
<input type="file" name="files[]" class="form-control" multiple="multiple"/>
</div>
<div class="mb-4">
<button type="submit" class="btn btn-blue">Upload</button>
</div>
</form>
</div>
</div>
</section>
</body>
</html>
 

Step 6: Upload Files to Google Drive Folder in PHP

We also need a server-side script that will handle the form submission and process files for upload. Create a PHP file to upload files to google drive in PHP using google client library. Steps to upload files to google drive are:

  • Include the autoload to load API client library.
  • Start a session to store error and success messages.
  • Initialize a new google client instance.
  • Set auth config of google client by providing the file location of service account credentials.
  • Add scopes to client for google drive and drive file.
  • Initialize new Google Service Drive instance proving it the $client as parameter.
  • Loop through all uploaded files.
  • If current file in loop has an error store the relevant message in session as array and skip the current iteration.
  • If file extension of current file in loop is not in allowed extensions store an appropriate message in session and skip current.
  • Create a new File Drive instance and set file name.
  • Set the parents providing the the folder id in google drive that we created. We can get that folder id from URL after navigating to that folder.
  • Finally, create a file in google drive passing it the first parameter the File Drive instance and second array parameter for file data, mime type and upload type.

google-drive-file-upload.php

<?php
include_once __DIR__ . '/vendor/autoload.php';

if (!session_id()) {
session_start();
}

$_SESSION['upload_errors'] = [];

// Initialize google client instance
$client = new Google_Client();

// Set service account config
$client->setAuthConfig('PATH_TO_SERVICE_ACCOUNT_CREDENTIALS');

// Set google drive and google drive file scopes
$client->setScopes([Google_Service_Drive::DRIVE, Google_Service_Drive::DRIVE_FILE]);

// Initialize google drive service
$drive = new Google_Service_Drive($client);

for ($i = 0; $i < count($_FILES['files']['name']); $i++) {
$extension = pathinfo($_FILES['files']['name'][$i], PATHINFO_EXTENSION);

$allowed_extensions = ['jpg', 'jpeg', 'png', 'gif'];

// If file has an upload error, store message in session and continue
if ($_FILES['files']['error'][$i] !== UPLOAD_ERR_OK) {
$_SESSION['upload_errors'][] = [
'file_name' => $_FILES['files']['name'][$i],
'message' => 'There was an error uploading this file'
];

continue;
}

// If file extension is not allowed, store message in session and continue
if (!in_array(strtolower($extension), $allowed_extensions)) {
$_SESSION['upload_errors'][] = [
'file_name' => basename($_FILES['files']['name'][$i]),
'message' => 'File extension is not allowed'
];
continue;
}

// Initialize a Drive File instance
$drive_file = new Google_Service_Drive_DriveFile();
$drive_file->setName($_FILES['files']['name'][$i]);
$drive_file->setParents(['YOUR_GOOGLE_DRIVE_FOLDER_ID']); // Add id of google drive folder

// Add/Create file on Google Drive
$file = $drive->files->create($drive_file, [
'data' => file_get_contents($_FILES['files']['tmp_name'][$i]), // File content
'mimeType' => mime_content_type($_FILES['files']['tmp_name'][$i]), // Mime type of the file
'uploadType' => 'multipart', // Upload type
]);

$_SESSION['success'] = true;
}

// Redirect user
header('Location: ' . filter_var($_SERVER['HTTP_REFERER'], FILTER_SANITIZE_URL));
exit;
 

Step 7: Add CSS Styles

Add some CSS for google drive file upload interface that contains file uploads form.

style.css

* {
box-sizing: border-box;
}
html,body {
margin: 0;
padding: 0;
}
body {
background-color: #f6f6f6;
font-family: "Segoe UI", "Roboto", "Helvetica", sans-serif;
font-size: 15px;
font-weight: normal;
font-style: normal;
}
.container {
max-width: 1024px;
margin: 0 auto;
padding-left: 15px;
padding-right: 15px;
}
.inline-block {
display: inline-block;
}
.py-4 {
padding-top: 1rem;
padding-bottom: 1rem;
}
.my-1, .mb-1 {
margin-bottom: .25rem;
}
.my-4, .mb-4 {
margin-bottom: 1rem;
}
.alert {
position: relative;
padding: .75rem 1.25rem;
margin-bottom: 1rem;
transition:opacity 0.5s;
}
.alert-green {
background-color: #319764;
border: 1px solid #248A57;
color: #ffffff;
}
.alert-red {
background-color: #e65442;
border: 1px solid #d94735;
color: #ffffff;
}
.errors-list {
list-style-position: inside;
padding-left: 0;
margin-top: 0;
margin-bottom: 0;
}
.form-control {
display: block;
width: 100%;
padding: .375rem .75rem;
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #1c2528;
background-color: #ffffff;
background-clip: padding-box;
border: 1px solid #d1d2d3;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
.btn {
display: inline-block;
padding: .375rem .75rem;
cursor: pointer;
font-size: inherit;
}
.btn-blue {
background-color: #0369a1;
border: 1px solid #0369a1;
color: #ffffff;
}
.btn-blue:hover {
background-color: #005D95;
}
 

We just implemented a file upload to google drive in PHP application using API client library of google. However there are important things to note here. 

  1. When we delete the uploaded file manually in google drive, the PHP application still shows those files. One work around this is to upload files via authentication approach.
  2. If you want to upload files to root of google drive and skip the folder part, You might need to assign some permissions to file after upload.
  3. It is good idea to store these files information in database after they have been uploaded to google drive.

We can assign permission to each file uploaded to google drive like this:

$permissions = new Google_Service_Drive_Permission();
$permissions->setType('user');
$permissions->setRole('writer');
$permissions->setEmailAddress('YOUR_GOOGLE_ACCOUNT_EMAIL');

// Apply the permission
$drive->permissions->create($file->id, $permissions);

The file list can be retrieved using the following code snippet:

$drive->files->listFiles()->getFiles()
 

Following code snippet is used to delete a file from google drive

$drive->files->delete($file->id);
 

If you face errors related to SSL issuer certificate in local environment, you might need to add cacert.pm to php.ini:

curl.cainfo ="path-to-file-directory/cacert.pem"
openssl.capath="path-to-file-directory/cacert.pem"