Desde hace tiempo he querido hacer un post completo sobre cómo trabajar con archivos ZIP en PHP.
Como sabemos, los archivos ZIP son unos paquetes que permiten tener dentro múltiples archivos para su posterior transporte.
PHP tiene soporte nativo para los archivos ZIP en la clase ZipArchive
y permite comprimir o empaquetar archivos de una manera fácil.
Hoy vamos a ver cómo:
Todavía no vamos a ver cómo descomprimir o desempaquetar, eso es de otro post.
Aviso: si al leer el post no sabes de dónde salen los archivos comprimidos, quieres ver la relación del código o te pierdes, te invito a ver y clonar el repositorio en GitHub 😉
Veamos el primer ejemplo. En el mismo creamos una nueva instancia de ZipArchive
. Abrimos el archivo zip con el método open
.
Al método open
le pasamos la ruta absoluta del zip y el modo de apertura. Lo estamos abriendo de modo que se cree si no existe y que se sobrescriba si ya existe.
Si no lo sobrescribimos y ya existe, se irán agregando más archivos al zip, ya que guardará los anteriores.
La parte importante para agregar un archivo es el método addFile
. Recibe dos argumentos: la ruta absoluta de la ubicación del archivo y su nombre. Ese nombre es el que tendrá dentro del zip.
Utilizamos basename
para limpiar el nombre, ya que algo como C:\fotos\perro.png se convierte en perro.png
De esta manera en el zip se añade el archivo con perro.png, aquí bien podrías cambiar el nombre del archivo.
Puedes llamar a addFile
cuantas veces quieras, solo recuerda que al final debes llamar al método close
; el cual devuelve un booleano
indicando si la escritura del archivo fue exitosa.
Al cerrar el archivo se habrá creado un zip en el directorio indicado.
En ocasiones vamos a necesitar crear un zip y mandarlo de regreso al usuario a través del navegador web.
Para ello utilizamos la función readfile en conjunto de algunos encabezados HTTP para forzar la descarga.
Primero creamos el archivo zip como normalmente se hace, y una vez que tenemos el archivo lo mandamos a través del navegador web.
Por cierto, si quieres eliminar el archivo al final simplemente invoca a unlink.
La clase ZipArchive
también permite agregar archivos basados en un patrón glob. Por ejemplo, para agregar todas las imágenes con extensión png podríamos indicarlas con el patrón *.png
De la misma manera todos los archivos de código fuente de Golang podrían agregarse con el patrón *.go
También soporta directorios: ./fotos/*.psd
Para agregar archivos basados en glob usamos el método llamado addGlob
:
Veamos algo interesante, se trata de agregar todo el contenido de un directorio recursivamente.
Es decir, si tenemos una carpeta y la misma tiene archivos todos los archivos son agregados.
Si dentro de la carpeta tenemos otra carpeta con contenido también se agrega. Y así infinitamente, por eso se dice que es de manera recursiva.
Para ello no existe un método como addDirRecursivePlease
, pero sí podemos recorrer manualmente un directorio de manera recursiva y llamar a addFile
en un ciclo.
Podemos recorrer un directorio de distintas maneras, en el ejemplo se utiliza un RecursiveDirectoryIterator
con un RecursiveIteratorIterator
.
No te preocupes ni compliques, simplemente vamos a iterar por un directorio de manera recursiva. Y dentro del ciclo agregar archivos.
En el ejemplo agregamos todo el contenido de imágenes, que a su vez tiene otros directorios. En cada iteración obtenemos la ruta absoluta del archivo.
Utilizamos substr
para agregar un nombre bonito o limpio como vimos anteriormente, pero no usamos basename
porque queremos respetar la profundidad de directorios.
Para terminar con los ejemplos veamos cómo agregar una contraseña al archivo zip y proteger los archivos con la misma.
Te aviso de una vez que esto de la contraseña y la protección de archivos funciona en PHP 7.2 y adelante.
Hay librerías y trucos para hacerlo funcionar en otras versiones, pero nosotros no vamos a ver eso. Te recomiendo encarecidamente que actualices tu versión de PHP en Windows, Android o Linux.
Lo que hay que notar aquí es el uso de setPassword
en el zip después de haberlo abierto, (solo se necesita una vez) así como el método setEncryptionName
que recibe el título del archivo (no su ruta absoluta) y el método de cifrado que es AES 256.
Fíjate en que setEncryptionName
es llamado después de agregar cada archivo.
Puedes combinar todos los ejemplos y adecuarlos a tus necesidades. Por ejemplo, descargar el archivo zip después de ponerle contraseña, agregar con glob y después agregar recursivamente, etcétera.
Los archivos que prestaron sus servicios para ser comprimidos son de otros posts como el de cron con Go, los fondos de escritorio de lenguajes de programación, la lectura y escritura de archivos Excel con PHP o el conversor de bases numéricas.
Recuerda que el código completo está en mi GitHub.
Muchas cosas presentes aquí fueron tomadas, inspiradas e investigadas de los siguientes enlaces (en serio, eran todas las pestañas que tenía mi navegador mientras hacía los ejemplos)
https://www.php.net/manual/es/book.zip.php
https://www.php.net/manual/es/ziparchive.setpassword.php
https://www.php.net/manual/es/ziparchive.addglob.php
https://github.com/parzibyte/marca_de_agua_php_personal/blob/master/marcar.php
https://stackoverflow.com/questions/39833496/zip-a-file-and-protect-with-a-password-in-php
https://php.net/manual/en/ziparchive.setencryptionname.php
La impresión de un PDF en cualquier impresora se puede automatizar con un bot de…
Hoy te enseñaré cómo enviar un mensaje a un usuario desde un bot de Telegram…
El día de hoy te enseñaré algo muy sencillo pero útil al programar con PHP:…
El plugin para imprimir en impresoras térmicas alcanza hoy su versión 3.4.0 agregando soporte para…
En ocasiones es necesario leer los pixeles y colores de una imagen con JavaScript del…
Siguiendo con los tutoriales de listas desplegables o select con JavaScript, vamos a ver cómo…
Esta web usa cookies.