Subir documentos a Google Drive con PHP

Facebook
Twitter
LinkedIn
WhatsApp
Subir documentos a Google Drive con PHP

Table of Contents

En ocasiones necesitamos usar servicios para alojar tus archivos o documentos en línea en la nube. Existen muchos servicios que ofrecen como Google Drive o Dropbox. Estos servicios ofrecen su API para web (o para otros entornos y lenguajes de programación). El que servicio que vamos a utilizar es es Google Drive, que pertenece a Google y es uno de los mejores servicios junto a otros para crear, eliminar, exportar, listar, etc. archivos en su plataforma.

¿Qúe es una API?

Una API es un conjunto de definiciones y protocolos que se utilizan para desarrollar e integrar el software de las aplicaciones. API significa interfaz de programación de aplicaciones.

Las API permiten que sus productos y servicios se comuniquen con otros, sin necesidad de saber cómo están implementados. Esto simplifica el desarrollo de las aplicaciones y permite ahorrar tiempo y dinero. Las API le otorgan flexibilidad; simplifican el diseño, la administración y el uso de las aplicaciones, y proporcionan oportunidades de innovación, lo cual es ideal al momento de diseñar herramientas y productos nuevos (o de gestionar los actuales).

Si queréis más información os dejo el siguiente enlace.

¿Qué APIS tiene Google?

Pues tienen API de cualquier producto de Google. Los más demandados son de Google Cloud, Google Maps, Android, Google Analytics, etc.

En este POST, vamos a ver el proceso de subir documentos a Google Drive con PHP utilizando la API de Google, por lo que vamos a mostrar cómo hacerlo paso a paso.

Explicación paso a paso

Configuración del servicio

Vamos a la web de Google API Console y pulsamos a «Nuevo Proyecto»

Subir documentos a Google Drive con PHP 1

En el buscador, buscamos la API «Google Drive API» y la habilitamos.

Subir documentos a Google Drive con PHP 3
Subir documentos a Google Drive con PHP 5

En el menú que se encuentra a la izquierda de Google Drive API, pulsamos a Credenciales.

Subir documentos a Google Drive con PHP 7

Pulsamos a Crear credenciales y nos saldrá un desplegable, por lo que tenemos que seleccionar «Cuenta de servicio».

Subir documentos a Google Drive con PHP 9

Rellenamos los datos del formulario, introducimos los datos para nuestra API:

Nombre de cuenta de servicio: lacodigoteca
ID de cuenta de servicio: lacodigoteca
Descripción de la cuenta de servicio: La codigoteca

Subir documentos a Google Drive con PHP 11

Ahora vamos a asignar permisos en la cuenta de la API. En este caso, vamos a darle permisos de Propietario.

Subir documentos a Google Drive con PHP 13

Pulsamos al correo electrónico que nos ha creado el servicio, y pulsamos añadir clave.

Subir documentos a Google Drive con PHP 15
Subir documentos a Google Drive con PHP 17

Al pulsar a añadir Clave, nos va a preguntar cómo queremos nuestra clave privada, en formato JSON o en P12. Vamos a seleccionar a JSON.

Subir documentos a Google Drive con PHP 19

Nos va descargar un fichero JSON en nuestro ordenador, en el que vamos a utilizar después.

Subir documentos a Google Drive con PHP 21

Permisos en nuestro Google Drive

Nos dirigimos a nuestro Google Drive y creamos una carpeta, en mi caso se llamará «lacodigoteca». Accedemos dentro de la carpeta y pulsamos a «Compartir»

Subir documentos a Google Drive con PHP 23

Añadimos el correo del servicio y le damos permisos de Editor.

Subir documentos a Google Drive con PHP 25

Restringiremos el acceso a la carpeta y copiaremos el enlace a compartir.

Subir documentos a Google Drive con PHP 27

En el enlace a compartir podemos ver cuál es el ID, os dejo un enlace de ejemplo con el ID en negrita.

https://drive.google.com/drive/folders/1qKTBAOXqB3d90OSubbp6Nvh10CQdFpXb?usp=sharing

Instalación de la librería Google API para PHP.

Nos dirigimos al repositorio de la librería Google API para PHP https://github.com/googleapis/google-api-php-client/releases

Subir documentos a Google Drive con PHP 29

Descargamos la última versión y descargamos el fichero ZIP con la versión de PHP que estamos utilizando en nuestro proyecto web. Con ello extraemos la carpeta y la dejamos en el directorio raíz de nuestro proyecto.

Archivo PHP (paso a paso)

Añadimos el archivo de la API a nuestro fichero .php


<?
include_once 'google-api-php-client-v2.7.2-PHP7.4/vendor/autoload.php';

Creamos una función en el que nos servirá para subir documentos a Google Drive:

En la variable $claveJSON indicaremos cual es la ID de la carpeta de Google Drive que hemos creado anteriormente.

En la variable $pathJSON , tenemos que poner el nombre del fichero JSON, que es el que tiene la clave para utilizar el servicio. El fichero JSON lo tengo alojado en la raíz del proyecto.


function subirDocumentoDrive($documento,$descripcion){
	// Variables de credenciales.
	$claveJSON = '1qKTBAOXqB3d90OSubbp6Nvh10CQdFpXb';
	$pathJSON = 'lacodigoteca-87cea347411f.json';
	
	//configurar variable de entorno
	putenv('GOOGLE_APPLICATION_CREDENTIALS='.$pathJSON);

	$client = new Google_Client();
	$client->useApplicationDefaultCredentials();
	$client->setScopes(['https://www.googleapis.com/auth/drive.file']);
	try{		
		//instanciamos el servicio
		$service = new Google_Service_Drive($client);

		//instacia de archivo
		$file = new Google_Service_Drive_DriveFile();
		$file->setName($documento);

		//obtenemos el mime type
		$finfo = finfo_open(FILEINFO_MIME_TYPE); 
		$mime_type=finfo_file($finfo, $documento);

		//id de la carpeta donde hemos dado el permiso a la cuenta de servicio 
		$file->setParents(array($claveJSON));
		$file->setDescription($descripcion);
		$file->setMimeType($mime_type);
		$result = $service->files->create(
		  $file,
		  array(
			'data' => file_get_contents($documento),
			'mimeType' => $mime_type,
			'uploadType' => 'media',
		  )
		);
		echo "2.- Fichero subido a Google Drive. 
"; }catch(Google_Service_Exception $gs){ $m=json_decode($gs->getMessage()); echo $m->error->message; }catch(Exception $e){ echo $e->getMessage(); } }

Diseñamos nuestro formulario HTML


<html>
	<head>
		<title>Subir ficheros a Google drive.</title>
	</head>
	<body>
		<form method="POST" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" enctype="multipart/form-data">
			<label for="documento">Documento:</label>
			<input type="file" name="documento" required /><br>
			<label for="descripcion">Descripción:</label>
			<input type="text" name="descripcion" required /><br>
			<input type="submit" name="enviar" value="Subir documento a Google Drive" />
		</form>
	</body>
</html>

Procedemos a subir nuestro fichero a nuestro servidor de manera temporal, ya que una vez subido a Google Drive, vamos a eliminarlo.

if($_SERVER["REQUEST_METHOD"] == "POST"){
	$documento = htmlspecialchars($_FILES['documento']['name']);
	$descripcion = htmlspecialchars($_POST['descripcion']);
	
	// Subimos el documento a nuestro servidor.
	if(move_uploaded_file($_FILES['documento']['tmp_name'], $documento)){
		echo "1.- Fichero subido al servidor. 
"; subirDocumentoDrive($documento,$descripcion); if (unlink($documento)){ echo "3.- Fichero eliminado del servidor"; }else{ echo 'Error: No se ha podido eliminar el documento "'.$documento.'" en el servidor.'; } }else{ echo "Error: Se ha producido un error, intentelo de nuevo."; } }

Archivo PHP (completo)


<?php
include_once 'google-api-php-client-v2.7.2-PHP7.4/vendor/autoload.php';

function subirDocumentoDrive($documento,$descripcion){
	// Variables de credenciales.
	$claveJSON = '1qKTBAOXqB3d90OSubbp6Nvh10CQdFpXb';
	$pathJSON = 'lacodigoteca-87cea347411f.json';

	//configurar variable de entorno
	putenv('GOOGLE_APPLICATION_CREDENTIALS='.$pathJSON);

	$client = new Google_Client();
	$client->useApplicationDefaultCredentials();
	$client->setScopes(['https://www.googleapis.com/auth/drive.file']);
	try{		
		//instanciamos el servicio
		$service = new Google_Service_Drive($client);

		//instacia de archivo
		$file = new Google_Service_Drive_DriveFile();
		$file->setName($documento);

		//obtenemos el mime type
		$finfo = finfo_open(FILEINFO_MIME_TYPE); 
		$mime_type=finfo_file($finfo, $documento);

		//id de la carpeta donde hemos dado el permiso a la cuenta de servicio 
		$file->setParents(array($claveJSON));
		$file->setDescription($descripcion);
		$file->setMimeType($mime_type);

		$result = $service->files->create(
		  $file,
		  array(
			'data' => file_get_contents($documento),
			'mimeType' => $mime_type,
			'uploadType' => 'media',
		  )
		);
		/* FICHERO SUBIDO A GOOGLE DRIVE */
		echo "2.- Fichero subido a Google Drive. 
"; }catch(Google_Service_Exception $gs){ $m=json_decode($gs->getMessage()); echo $m->error->message; }catch(Exception $e){ echo $e->getMessage(); } } if($_SERVER["REQUEST_METHOD"] == "POST"){ $documento = htmlspecialchars($_FILES['documento']['name']); $descripcion = htmlspecialchars($_POST['descripcion']); // Subimos el documento a nuestro servidor. if(move_uploaded_file($_FILES['documento']['tmp_name'], $documento)){ echo "1.- Fichero subido al servidor.
"; subirDocumentoDrive($documento,$descripcion); if (unlink($documento)){ echo "3.- Fichero eliminado del servidor"; }else{ echo 'Error: No se ha podido eliminar el documento "'.$documento.'" en el servidor.'; } }else{ echo "Error: Se ha producido un error, intentelo de nuevo."; } } ?> <html> <head> <title>Subir ficheros a Google drive.</title> </head> <body> <form method="POST" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" enctype="multipart/form-data"> <label for="documento">Documento:</label> <input type="file" name="documento" required /><br> <label for="descripcion">Descripción:</label> <input type="text" name="descripcion" required /><br> <input type="submit" name="enviar" value="Subir documento a Google Drive" /> </form> </body> </html>

Nuevo: Renovar token automáticamente de Google Drive

Creamos un archivo que se llame auth.php con la función getAccessToken() para obtener el token actualizado:

<?php

require_once __DIR__ . '/vendor/autoload.php';

function getAccessToken() {
    $client = new Google_Client();
    $client->setAuthConfig('credentials.json');
    $client->addScope(Google_Service_Drive::DRIVE);

    $accessToken = json_decode(file_get_contents('access_token.json'), true);
    $client->setAccessToken($accessToken);

    if ($client->isAccessTokenExpired()) {
        $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
        file_put_contents('access_token.json', json_encode($client->getAccessToken()));
        $accessToken = $client->getAccessToken();
    }

    return $accessToken['access_token'];
}

Después creamos una función checkAccessToken() que compruebe si el token actualizado existe y si no, obtenga uno nuevo utilizando la función getAccessToken():

function checkAccessToken() {
    if (file_exists('access_token.json')) {
        $accessToken = json_decode(file_get_contents('access_token.json'), true);

        if (!$accessToken || !isset($accessToken['access_token'])) {
            $accessToken = getAccessToken();
        }
    } else {
        $accessToken = getAccessToken();
    }

    return $accessToken['access_token'];
}

Utilizaremos la función checkAccessToken() en el código donde se utiliza la API de Google Drive:

<?php

require_once __DIR__ . '/vendor/autoload.php';

$client = new Google_Client();
$client->setAuthConfig('credentials.json');
$client->setAccessToken(checkAccessToken());

$service = new Google_Service_Drive($client);

// Ejemplo de uso de la API de Google Drive
$files = $service->files->listFiles(array('pageSize' => 10));
foreach ($files->getFiles() as $file) {
    echo $file->getName();
}

Nota: Si queréis subir varios documentos a Google Drive con PHP a la vez, os recomiendo que echéis un vistazo al siguiente post:

Facebook
Twitter
LinkedIn

22 comentarios en “Subir documentos a Google Drive con PHP”

  1. Sandor Luque Farfán

    Hola buenas tardes..Mira me saca error:

    Fatal error: Uncaught Error: Class ‘Google\Client’ not found in D:\xampp\htdocs\UpdateDocumentsGoogleDrive\updateFilesGdrive.php:37 Stack trace: #0 D:\xampp\htdocs\UpdateDocumentsGoogleDrive\updateFilesGdrive.php(11): subirDocumentoDrive(‘Captura_req_red…’, ‘Prueba-7’) #1 {main} thrown in D:\xampp\htdocs\UpdateDocumentsGoogleDrive\updateFilesGdrive.php on line 37

    1. Hola!
      ¿Tienes bien enlazado el autoload? Comprueba la ruta. También deberás de comprobar qué versión de PHP estás utilizando, el ejemplo se realizó con PHP 7.4.
      Espero que se haya resuelto el error.

      Un saludo.

  2. Hola, muy buen articulo. ¿Hay alguna forma de conseguir el link una vez subido el archivo? Me gustaría poder guardar el link a cada documento que subo a google drive en mi base de datos. Gracias!

    1. Hola Joaquín,

      Me alegro que te sirviera el artículo. Para sacar el enlace, debes de usar la variable $result. Te dejo un breve ejemplo:

      echo 'https://drive.google.com/open?id='.$result->id

      Si quieres probarlo, debes de ponerlo justo debajo de la anotación:
      echo "2.- Fichero subido a Google Drive.
      ";

      Un saludo.

  3. Buenas!

    Antes que nada agradecerte el codigo ha ido perfecto! La duda que tengo es que lo utilizo en un formulario que se rellena a traves de un movil, entonces como podria redimensionar las imagenes ?

    Muchas gracias

    1. Hola Miguel,
      Me alegro un montón que te sirva de ayuda mi blog 🙂 Es una pregunta ambigüa, te refieres a que, al subir la foto a Google Drive, ¿se redimensione las imágenes? Para ello puedes utilizar imagescale de PHP. Si es para mostrar esa imagen en un formulario, deberás de trabajar un CSS responsive con media queries.

      Un saludo.

      1. Buenas !

        Si, voy a usar tu codigo para una aplicacion de tickets y se generan unos 200 al dia, entonces des de un dipositivo movil la calidad de las fotos son altas, hay alguna forma de que antes de subirlas a google drive les baje la resolucion? He buscando de diferentes maneras pero no logro encontrar la clave correcta

  4. Hola, habría alguna forma de acceder a los subdirectorios del directorio compartido en Drive? Necesitaría que un usuario pudiera subir archivos a su carpeta en Drive. Gracias

  5. Sandor Luque Faf{an

    Hola como hago para renovar automaticamente el token que despues de cierta cantidad de subida de archivos se llena las cuotas y acceso al token. Si me puedes compartir el codigo o donde tener una guia te lo agradezco

  6. Hola, ya hice todo pero me salen 2 errores en el $file = new Google_Service_DriveFile() y en el $service = new Google_Service_Drive($client);
    Los 2 errores son en el Google_service

    1. Hola Fernando,

      Comprueba que tienes la librería de Google Drive en la raíz de tu fichero o donde lo tengas apuntando la librería en el include_once.

      Comprueba también qué versión de PHP tienes, ya que este ejemplo está basado en la 7.4.

      Un saludo.

  7. Buen día excelente, me sirvió mucho, compré espacio en Google One pero subo y subo cosas y no consume el espacio y la cuenta de servicio se llena a las 15 gigas, me toca borrar la cuenta se servicio y crear otra; como hago para que consuma el espacio de mi cuenta, es que como si archivo que se sube fuera compartido de la cuenta de servicio a la mia y no queda realmente en cuenta.

  8. Hola, me he perdido un poco en la parte de la generación de los tokens.
    Que datos deberían tener los archivos access_token.json y credentials.json ya que no lo dice por ningún lado.
    Perdona si mi pregunta raya en lo obvio, pero no logro hacer funcionar esa última parte

    1. Hola Eduardo,
      Disculpa por la tardanza. He revisado tu comentario y los ficheros. Tanto acces_token.json ($claveJSON) como credentials.json ($pathJSON) deberás de invocarlo desde el fichero PHP que permite subir ficheros a Google drive.

      Un saludo.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Scroll al inicio