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 a PHP application.

Upload Files to Google Drive in PHP

In addition to 15GB of free storage, it is possible to get extra storage by paying a monthly fee. It is possible to upload files to Google Drive from a web application using service account credentials. In this post, we will learn how to upload multiple files to Google Drive using a service account in PHP. Files we are going to create for this post:

  1. index.php: The HTML page with a 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 the 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 the Google API client library, and processing file uploads on the server-side. We are going to create an HTML form with a file upload field allow it to upload multiple files. The following steps are to be followed to implement file upload to Google Drive in PHP using an API client library.

 

Step 1: Install Google API Client Library (PHP)

We need the 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 the Google Drive API from a PHP application. To create a project in Cloud Console, go to Google Cloud Console and create a new project or use an existing one.

  • Click on "New Project" or select an existing one from the projects list.
  • Enter a project name in the 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 the left navigation menu, click "IAM and admin".
  • Click on "Service accounts" in the submenu.
  • Click on "+ Create service account".
  • Enter a service account name and description if needed.
  • Click on "Done".
  • Click the "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 the application's project directory.
Create Service Account and Download Credentials
 

Step 4: Create a Drive Folder and Share it With The 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 the email address of the 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 the left side menu.
  • From the dropdown, select "Folder" and enter a name for the folder.
  • Click on "Create" and it will create a new folder in Google Drive.
  • Right-click on the folder you just created and click "+ Share".
  • In the input field, enter the email address of the service account we created in the previous step.
  • Click on "Done".
 

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

Now,  after Google side configurations are complete, we need a user interface in a web application from which files can be uploaded to Google Drive. Create an index PHP file containing an HTML form with an input file field to upload files to Google Drive from the website:

  • Add the attribute enctype="multipart/form-data" to allow file uploads.
  • Add an attribute multiple to the file input field to allow selection of multiple files at once.
  • Add a container above the form for a success message when the user redirects to this page after successful upload.
  • Add a container above the form for error messages to display after the user has been redirected to this page from a 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 the Google client library. Steps to upload files to Google Drive are:

  • Include the autoload to load the API client library.
  • Start a session to store error and success messages.
  • Initialize a new Google client instance.
  • Set Google client's auth config by providing the file location of the service account credentials.
  • Add scopes to the client for Google Drive and the drive file.
  • Initialize a new Google Service Drive instance proving it the $client as a parameter.
  • Loop through all uploaded files.
  • If the current file in the loop has an error, store the relevant message in the session as an array and skip the current iteration.
  • If the file extension of the current file in the loop is not in the allowed extensions, store an appropriate message in the session and skip the current file upload.
  • Create a new File Drive instance and set the file name.
  • Set the parents, providing the folder ID in Google Drive that we created. We can get that folder ID from the URL after navigating to that folder.
  • Finally, create a file in Google Drive passing it the first parameter, the File Drive instance and the 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 the Google Drive file upload interface that contains the file upload 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 a PHP application using the 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 workaround for this is to upload files via an authentication approach.
  2. If we want to upload files to the root of Google Drive and skip the folder part, we might need to assign some permissions to the file after upload.
  3. It is a good idea to store this information in a database after files have been uploaded to Google Drive.

We can assign permissions 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');

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

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

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

We can also delete a file from Google Drive using the following code snippet:

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

We might also need to download and assign the cacert.pm file in php.ini to avoid any SSL issuer certificate related errors in the local environment:

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