Saltar al contenido

Cómo [recursively] ¿Comprimir un directorio en PHP?

Solución:

Aquí hay una función simple que puede comprimir cualquier archivo o directorio de forma recursiva, solo necesita que se cargue la extensión zip.

function Zip($source, $destination)
{
    if (!extension_loaded('zip') || !file_exists($source)) {
        return false;
    }

    $zip = new ZipArchive();
    if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
        return false;
    }

    $source = str_replace('\', "https://foroayuda.es/", realpath($source));

    if (is_dir($source) === true)
    {
        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);

        foreach ($files as $file)
        {
            $file = str_replace('\', "https://foroayuda.es/", $file);

            // Ignore "." and ".." folders
            if( in_array(substr($file, strrpos($file, "https://foroayuda.es/")+1), array('.', '..')) )
                continue;

            $file = realpath($file);

            if (is_dir($file) === true)
            {
                $zip->addEmptyDir(str_replace($source . "https://foroayuda.es/", '', $file . "https://foroayuda.es/"));
            }
            else if (is_file($file) === true)
            {
                $zip->addFromString(str_replace($source . "https://foroayuda.es/", '', $file), file_get_contents($file));
            }
        }
    }
    else if (is_file($source) === true)
    {
        $zip->addFromString(basename($source), file_get_contents($source));
    }

    return $zip->close();
}

Llámalo así:

Zip('/folder/to/compress/', './compressed.zip');

Otro archivado de árbol de directorios recursivo, implementado como una extensión de ZipArchive. Como beneficio adicional, se incluye una función auxiliar de compresión de árbol de declaración única. Se admite el nombre local opcional, como en otras funciones de ZipArchive. Error de manejo del código que se agregará …

class ExtendedZip extends ZipArchive {

    // Member function to add a whole file system subtree to the archive
    public function addTree($dirname, $localname="") {
        if ($localname)
            $this->addEmptyDir($localname);
        $this->_addTree($dirname, $localname);
    }

    // Internal function, to recurse
    protected function _addTree($dirname, $localname) {
        $dir = opendir($dirname);
        while ($filename = readdir($dir)) {
            // Discard . and ..
            if ($filename == '.' || $filename == '..')
                continue;

            // Proceed according to type
            $path = $dirname . "https://foroayuda.es/" . $filename;
            $localpath = $localname ? ($localname . "https://foroayuda.es/" . $filename) : $filename;
            if (is_dir($path)) {
                // Directory: add & recurse
                $this->addEmptyDir($localpath);
                $this->_addTree($path, $localpath);
            }
            else if (is_file($path)) {
                // File: just add
                $this->addFile($path, $localpath);
            }
        }
        closedir($dir);
    }

    // Helper function
    public static function zipTree($dirname, $zipFilename, $flags = 0, $localname="") {
        $zip = new self();
        $zip->open($zipFilename, $flags);
        $zip->addTree($dirname, $localname);
        $zip->close();
    }
}

// Example
ExtendedZip::zipTree('/foo/bar', '/tmp/archive.zip', ZipArchive::CREATE);

He editado la respuesta de Alix Axel para tomar un tercer argumento, al establecer este tercer argumento en true todos los archivos se agregarán en el directorio principal en lugar de directamente en la carpeta zip.

Si el archivo zip existe, el archivo también se eliminará.

Ejemplo:

Zip('/path/to/maindirectory','/path/to/compressed.zip',true);

Tercer argumento true estructura de cremallera:

maindirectory
--- file 1
--- file 2
--- subdirectory 1
------ file 3
------ file 4
--- subdirectory 2
------ file 5
------ file 6

Tercer argumento false o estructura de cremallera faltante:

file 1
file 2
subdirectory 1
--- file 3
--- file 4
subdirectory 2
--- file 5
--- file 6

Código editado:

function Zip($source, $destination, $include_dir = false)
{

    if (!extension_loaded('zip') || !file_exists($source)) {
        return false;
    }

    if (file_exists($destination)) {
        unlink ($destination);
    }

    $zip = new ZipArchive();
    if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
        return false;
    }
    $source = str_replace('\', "https://foroayuda.es/", realpath($source));

    if (is_dir($source) === true)
    {

        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);

        if ($include_dir) {

            $arr = explode("https://foroayuda.es/",$source);
            $maindir = $arr[count($arr)- 1];

            $source = "";
            for ($i=0; $i < count($arr) - 1; $i++) { 
                $source .= "https://foroayuda.es/" . $arr[$i];
            }

            $source = substr($source, 1);

            $zip->addEmptyDir($maindir);

        }

        foreach ($files as $file)
        {
            $file = str_replace('\', "https://foroayuda.es/", $file);

            // Ignore "." and ".." folders
            if( in_array(substr($file, strrpos($file, "https://foroayuda.es/")+1), array('.', '..')) )
                continue;

            $file = realpath($file);

            if (is_dir($file) === true)
            {
                $zip->addEmptyDir(str_replace($source . "https://foroayuda.es/", '', $file . "https://foroayuda.es/"));
            }
            else if (is_file($file) === true)
            {
                $zip->addFromString(str_replace($source . "https://foroayuda.es/", '', $file), file_get_contents($file));
            }
        }
    }
    else if (is_file($source) === true)
    {
        $zip->addFromString(basename($source), file_get_contents($source));
    }

    return $zip->close();
}
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

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