Crear un Zip on the fly amb PHP (compatible amb Windows, Linux i MAC OSX)
El 12/08/2010 a les 20:33
Algunes de les llibreries que trobem a Internet per crear Zips, tenen un error, no es poden descomprimir amb la utilitat de descompressió de Mac OSX. Com podem fer-ho?
El mètode consisteix a fer servir la classe ZipArchive de PHP per crear el zip en un directory y un cop creat forçar-ne la descàrrega amb les capçaleres adequades. Per últim eliminar el fitxer.
ZipArchive permet Crear o Modificar arxius ZIP. Hem de treballar sempre amb un nom de fitxer diferent per evitar que a l'obrir modifiquem l'anterior o el fitxer d'un altre usuari.
Començem creant el fitxer, definim el directori de treball i escollim un nom de fitxer aleatori, així cap usuari modificarà el Zip d'un altre usuari que està treballant al mateix temps o un zip creat anteriorment.
$path='./temp/';
$zip = new ZipArchive();
$filename = $path."temp".rand(1000,2000).".zip";
if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
exit("cannot open <$filename>\n");
}
Tenim 2 maneres de afegir fitxers, la primera és afegir directament el fitxer des de un directori, i la segona crear un fitxer nou des d'un string:
$zip->addFile('upload/foto01.jpg, 'foto_principal.jpg');
$zip->addFromString($folder.'readme.txt','Soc un fitxer de text');
Crearem el fitxer Zip en un directori:
$zip->addFromString('playlist.m3u',$m3u);
$zip->close();
És molt possible que el que ens interessi sigui descarregar el fitxer al vol des del navegador, en lloc de guardar-lo en un directori físicament. El que farem és escriure el fitxer i forçar-ne la descarrega amb el nom pertinent utilitzant la funció header de PHP. Fixeu-vos que perquè no hi hagi problemes amb els espais en el nom del fitxer el poso entre cometes. Per últim eliminem el fitxer:
header("Content-type: application/octet-stream"); header("Content-Transfer-Encoding: binary");
$len=filesize($filename);
header("Content-Length: $len");
header("Content-disposition: attachment; filename=\"".Nom del fitxer.zip\"");
readfile($filename);
unlink($filename);
Per últim comentar que aquest méstode te un error, si obrim la finestra de descàrregaperó la tanquem molt ràpid, el fitxer no s'elimina, no te temps de fer l'unlink. Per solucionar-ho podem posar al principi del fitxer una funció que recorri el directori temporal i elimini els zips creata fa un parell de dies.
$handle=opendir($path);
while (false!==($file = readdir($handle))) {
if (ereg('.zip',$file)) {
$diff = (time() - filectime($path.$file))/60/60/24;
if ($Diff > 1) unlink($path.$file);
}
}
closedir($handle);
T'ha set d'utilitat l'article? vols simplent afegir-hi alguna cosa?
Siusplau comenta-ho...