Descomprimir y recorrer archivo ZIP en PHP

En este artículo vamos a ver:

Descomprimir un archivo ZIP en un directorio
Leer y obtener información de los archivos ZIP descomprimidos.

Para ello primero vamos a tener un documento HTML donde subiremos el archivo ZIP.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Descomprimir ZIP</title>
</head>
   <body>
      <form enctype="multipart/form-data" method="post" action="maneja.php">
         <label>Subir archivo ZIP: <input type="file" name="zip_file" /></label>
         <br />
         <input type="submit" name="submit" value="Subir" />
      </form>
   </body>
</html>

Cuando pulsemos el botón subir nos enviará a maneja.php (nuestro documento .php).

En ese fichero están definidas tres funcionalidades diferentes (No usar las tres a la vez).

FUNCIONALIDAD 1: Descomprimir ZIP en carpeta destino.
FUNCIONALIDAD 2: Leemos información del archivo ZIP y después descomprimimos en carpeta destino.
FUNCIONALIDAD 3: Leemos directamente de nuestro archivo ZIP y mostramos contenido de los archivos almacenados en dicho ZIP.

Esta parte es genérica para las tres funcionalidades:

//comprobamos si se ha recibido el nombre del ZIP
if ($_FILES["zip_file"]["name"]) 
{
    //obtenemos datos de nuestro ZIP
    $nombre = $_FILES["zip_file"]["name"];
    $ruta = $_FILES["zip_file"]["tmp_name"];
    $tipo = $_FILES["zip_file"]["type"];
 
    // --> AQUÍ INCLUIR ALGUNA DE LAS TRES FUNCIONALIDADES <--
}

FUNCIONALIDAD 1 -> Descomprimir ZIP en carpeta

    $zip = new ZipArchive;
	//en la función open se le pasa la ruta de nuestro archivo (alojada en carpeta temporal)
	if ($zip->open($ruta) === TRUE) 
	{
		//función para extraer el ZIP, le pasamos la ruta donde queremos que nos descomprima
		$zip->extractTo('almacen/');
		$zip->close();
	}

FUNCIONALIDAD 2 -> Leemos directamente de nuestro archivo ZIP y lo recorremos obteniendo su nombre y ruta y después descomprimir el ZIP

//creamos un array para guardar el nombre de los archivos que contiene el ZIP
$nombresFichZIP = array();
$zip = new ZipArchive;
 
if ($zip->open($ruta) === TRUE)
{
   for($i = 0; $i < $zip->numFiles; $i++)
   {
	//obtenemos ruta que tendrán los documentos cuando los descomprimamos
	$nombresFichZIP['tmp_name'][$i] = 'almacen/'.$zip->getNameIndex($i);
	//obtenemos nombre del fichero
	$nombresFichZIP['name'][$i] = $zip->getNameIndex($i);
   }
 
   //descomprimimos zip
   $zip->extractTo('almacen/');
   $zip->close();
}
/*RESULTADO (de la lectura de ruta y nombre de los ficheros):
Array ( 
   [tmp_name] => Array ( 
		       [0] => almacen/archivo1.xml 
		       [1] => almacen/archivo2.xml ) 
       [name] => Array ( 
		       [0] => archivo1.xml 
		       [1] => archivo2.xml ) ) 
*/

FUNCIONALIDAD 3 –> Recorrer ZIP y leer el contenido de sus ficheros

$zip = zip_open($ruta);
if($zip)
{
    //la función zip_read sirve para leer el contenido de nuestro archivo ZIP
    while ($zip_entry = zip_read($zip))
    {
       // la función zip_entry_name devuelve el nombre de cada uno de nuestros archivos. 
       echo "<p>Nombre del archivo: " . zip_entry_name($zip_entry) . "<br />\n";
       echo "<br/>";
       if(zip_entry_open($zip, $zip_entry))
       {
	   echo "Contenido documento: <br/>";
	   //la función zip_entry_read lee el contenido del fichero
	   $contenido = zip_entry_read($zip_entry);
	   print_r($contenido);
	   echo "<br/><br/>";
	}
    }
}
 
/*RESULTADO (nombre del fichero y visualización de su contenido):
Nombre del archivo: archivo1.xml
Contenido documento: 
Contenido del fichero 1
 
Nombre del archivo: archivo2.xml
Contenido documento: 
Contenido del fichero 2
*/

Iván Martínez

Ingeniero Informático apasionado por el mundo del desarrollo WEB. Me gusta caminar por este mundo lleno de tecnologías y día a día aprender cosas nuevas como el doctor Frankenstein ¡dadme cosas para experimentar!

Deja un comentario

Tu dirección de correo electrónico no será publicada.