Spanish (Español) translation by Rene Soto (you can also view the original English article)
Comprimir archivos al transferirlos a través de Internet tiene muchas ventajas. En la mayoría de los casos, el tamaño total combinado de todos los archivos en el formato comprimido se reduce por un margen agradable. Esto significa que ahorrarás parte de tu ancho de banda, y los usuarios también obtendrán velocidades de descarga más rápidas. Una vez que los usuarios han descargado un archivo, pueden descomprimirlo cuando lo deseen. En resumen, la compresión puede hacer que el servicio de archivos a través de Internet sea mucho más fácil para ti y para tus visitantes.
Un factor que puede impedirte comprimir archivos o hacer que el proceso sea muy aburrido es el hecho de que puede hacerlo manualmente. Afortunadamente, PHP viene con muchas extensiones que tratan específicamente con la compresión y extracción de archivos. Puedes usar las funciones disponibles en estas extensiones para comprimir automáticamente los archivos en PHP.
Este tutorial te enseñará cómo comprimir y descomprimir(comprimir y extraer) archivos hacia y desde un archivo zip en PHP. También aprenderás cómo eliminar o renombrar archivos en un archivo sin extraerlos primero.
Comprimiendo Archivos en PHP
La clase PHP ZipArchive
tiene muchas propiedades y métodos
que pueden ayudar a comprender y descomprimir todos tus archivos.
Comprimir Archivos Individuales
Puedes agregar archivos a tu archivo zip uno por uno o
agregar todo el directorio a la vez. Una nueva instancia de ZipArchive
y luego
llamar al método open($filename, [$flags])
. Este método abrirá un nuevo archivo zip para leer, escribir u otras modificaciones. Hay cuatro valores válidos para el parámetro opcional $flag
que determina cómo manejar diferentes situaciones.
-
ZipArchive :: OVERWRITE
- Esta bandera sobrescribirá el contenido en el archivo especificado si ya existe. -
ZipArchive :: CREATE
- Esta bandera creará un nuevo archivo si aún no existe. -
ZipArchive :: EXCL
- Este indicador dará como resultado un error si el archivo ya existe. -
ZipArchive :: CHECKCONS
- Esta bandera le indicará a PHP que realice verificaciones de consistencia adicionales en el archivo y dará un error si fallan.
Puedes consultar la documentación de este método para
obtener información sobre los diferentes códigos de error devueltos en caso de
fallas para abrir el archivo.Si el archivo zip se abrió o creó correctamente, el método
devolverá true
Una vez que hayas abierto el archivo con éxito, puedes usar
el método addFile($filename, $localname, $start, $length)
para agregar
cualquier archivo de una ruta determinada a tu archivo. El parámetro $filename
es la ruta de un archivo que desea agregar al archivo. El parámetro $localname
se utiliza para asignar un nombre al archivo para almacenarlo dentro del archivo. Puede llamar a addFile()
cada vez que desee agregar un nuevo archivo a su archivo.
Después de agregar todos los archivos necesarios al archivo,
simplemente puedes llamar al método close()
para cerrarlo y guardar los
cambios.
Digamos que tienes un sitio web que permite a los usuarios descargar archivos de fuentes para diferentes fuentes junto con la información de licencia para usarlos. Archivos como estos serán ejemplos perfectos de archivo automatizado usando PHP. El siguiente código te muestra cómo hacer exactamente eso.
<?php $zip = new ZipArchive(); $zip->open('compressed/font_files.zip', ZipArchive::CREATE); $zip->addFile('fonts/Monoton/Monoton-Regular.ttf', 'Monoton-Regular.ttf'); $zip->addFile('fonts/Monoton/OFL.txt', 'license.txt'); $zip->close(); ?>
Comenzamos creando una instancia de ZipArchive
y luego
usando el método open()
para crear nuestro archivo. El método addFile()
agrega
nuestro archivo de fuente .ttf real y el archivo de licencia .txt al archivo.
Debes tener en cuenta que los archivos originales estaban dentro del directorio de fonts/Monoton. Sin embargo, el código PHP lo coloca directamente dentro de la raíz de nuestro archivo. Puedes cambiar la estructura del directorio, así como los nombres de los archivos que van en el archivo.
Comprimiendo Múltiples Archivos de un Directorio
Agregar archivos individuales a tu archivo puede resultar
agotador después de un tiempo. Por ejemplo, es posible que desees crear un
archivo de todos los archivos .pdf o .png en un directorio. El método addGlob($pattern, $flags, $options)
será muy útil en este caso. La única desventaja de este método es que pierde el control sobre la ubicación de los archivos individuales en el archivo. Sin embargo, aún puede influir en la estructura de directorios dentro del archivo usando el parámetro $options
. Las opciones se pasan en forma de una matriz asociativa.
-
add_path
: el valor que asigna aadd_path
es prefijado a la ruta local del archivo dentro del archivo. -
remove_path
: el valor que asigna aremove_path
se usa para eliminar un prefijo coincidente de la ruta de los diferentes archivos que se agregan al archivo. -
remove_all_path
: establecer el valor deremove_all_path
entrue
eliminará todo lo que haya en la ruta del archivo, además de su nombre. En este caso, los archivos se agregan a la raíz del archivo.
Es importante recordar que la eliminación de una ruta se
realiza antes de prefijar el valor especificado en add_path
.
El siguiente fragmento de código hará que el uso de
addGlob()
y todas estas opciones sea más claro.
$zip = new ZipArchive(); $zip->open('compressed/user_archive.zip', ZipArchive::CREATE); $options = array('add_path' => 'light_wallpapers/', 'remove_all_path' => TRUE); $zip->addGlob('lights/*.jpg', 0, $options); $options = array('add_path' => 'font_files/', 'remove_all_path' => TRUE); $zip->addGlob('documents/*.ttf', 0, $options); $options = array('add_path' => 'pdf_books/', 'remove_all_path' => TRUE); $zip->addGlob('documents/*.pdf', 0, $options); $options = array('add_path' => 'images/', 'remove_all_path' => TRUE); $zip->addGlob('documents/*.{jpg, png}', GLOB_BRACE, $options); $zip->close();
Como de costumbre, comenzamos creando una instancia de
ZipArchive
y luego usamos el método open()
para crear nuestro archivo. También especificamos diferentes valores para la clave add_path
en la matriz $options
cada vez antes de llamar al método addGlob()
. De esta manera, podemos tratar con un conjunto específico de archivos a la vez y proporcionar las opciones de archivo correspondientes.
En el primer caso, iteramos sobre todos los archivos .jpg en el directorio lights y los colocamos en el directorio light_wallpapers en el archivo. Del mismo modo, iteramos sobre todos los archivos .ttf en el directorio de documents y luego los colocamos en una carpeta llamada font_files en nuestro archivo. Finalmente, repasamos todos los archivos .jpg y .png en nuestros documentos a la vez y los reunimos en el directorio images.
Como puedes ver, los valores en el parámetro $options
son
útiles para organizar el contenido dentro del archivo.
Extraer Contenido de un Archivo
La clase ZipArchive
tiene un método llamado
extractTo($destination, $entries)
para extraer el contenido de un archivo.
Puede usarlo para extraer todo dentro del archivo o solo algunos archivos
específicos. El parámetro $entries
se puede usar para especificar un solo nombre de archivo que se va a extraer, o puedes usarlo para pasar una matriz de archivos.
Un punto importante a recordar es que necesitas especificar
la ruta correcta del archivo dentro del archivo para poder extraerlo. Por
ejemplo, archivamos un archivo de fuente llamado AlegreyaSans-Light.ttf en la
sección anterior. El archivo se almacenó dentro del archivo en un directorio
llamado font_files. Esto significa que la ruta que debes especificar en el
parámetro $entries
sería font_files/AlegreyaSans-Light.ttf y no simplemente
AlegreyaSans-Light.ttf.
El directorio y la estructura de archivos se conservarán durante el proceso de extracción, y los archivos se extraerán en sus respectivos directorios.
<?php $zip = new ZipArchive(); $zip->open('compressed/user_archive.zip', ZipArchive::CREATE); $zip->extractTo('uncompressed/', 'font_files/AlegreyaSans-Light.ttf'); $zip->close(); ?>
Si omite el segundo parámetro, el método extraerá todos los archivos en el archivo.
Obtener más Control Sobre los Archivos
La clase ZipArchive
también tiene muchos otros métodos y
propiedades para ayudarte a obtener más información sobre el archivo antes de
extraer todo su contenido.
Puede contar la cantidad de archivos en un archivo usando el
método count()
. Otra opción es usar la propiedad numFiles
. Se pueden usar para recorrer todos los archivos del archivo y solo extraer los que necesitas, o puede hacer algo más con ellos, como eliminarlos del archivo.
En el siguiente ejemplo, estamos eliminando todos los archivos del archivo que contienen la palabra Italic. Se podría usar un código similar para eliminar todos los archivos que no contienen una palabra específica. También puede iterar sobre estos archivos y reemplazar una palabra en particular con otra cosa.
<?php $zip = new ZipArchive(); $zip->open('compressed/user_archive.zip', ZipArchive::CREATE); $file_count = $zip->count(); for($i = 0; $i < $file_count; $i++) { $file_name = $zip->getNameIndex($i); if(stripos($file_name, 'Italic') !== false) { $zip->deleteName($file_name); } } $zip->close(); ?>
En el código anterior, estamos usando deleteName()
para
eliminar un archivo individual. Sin embargo, también puedes utilizarlo para
eliminar un directorio completo.
Se puede usar una función similar renameName($oldname,
$newname)
para cambiar el nombre de cualquier archivo en el archivo. Recibirás
un error si ya existe un archivo titulado $newname
.
Conclusiones Finales
Hemos cubierto un montón de métodos muy útiles de la clase
ZipArchive
que harán que la compresión y extracción automatizada de archivos en
PHP sea muy fácil. Ahora deberías poder comprimir archivos individuales o un grupo de ellos a la vez, según tus propios criterios. Del mismo modo, debes poder extraer cualquier archivo particular del archivo sin afectar a otro contenido.
Con la ayuda de count()
y numFiles
, obtendrás más control
sobre los archivos individuales, y cambiar el nombre o eliminarlos sería súper
fácil. Debes leer la documentación al menos una vez para leer más sobre dichas
funciones.