New question

Question:

Date: 13-11-2015 01:16:51 (In Spanish)

¿Cómo manejar archivos zip?[Resolved]

Buenas tengo una aplicación web en php y necesito que suba un archivo zip que tiene password, muestra el siguiente aviso y no abre el archivo "Warning: ZipArchive::setPassword(): Invalid or uninitialized Zip object".

Servidor Sistema Operativo: Debian 8 Jessie.
PHP: PHP 5.6.14-0+deb8u1
Mysql: mysql Ver 14.14 Distrib 5.5.46
Apache: Apache/2.4.10
PECL zip 1.13.1

El directorio tiene permisos de lectura y escritura donde realizo los uploads de archivos temporales.
Si alguien pudo realizar algo similar y me da una mano les agradeceria.

Tags: Development - Error - PHP - PHP Advanced - Question - Server - ZIP Votes: 0 - Answers: 6 - Views: 12 Share on: Google Facebook Twitter LinkedIn Link
 

Answers:

  • Date: 13-11-2015 04:49:38 Hola Hernan , puedes poner tu linea de codigo para ver las lineas y asi poder ayudarte , saludos   Votes: 2 - Link answer
     
  • Date: 13-11-2015 05:28:37 Ese error generalmente sucede cuando el archivo no está en el lugar especificado.
    Si compartes tu código te podremos ayudar mejor
      Votes: 1 - Link answer
     
  • Date: 17-11-2015 02:10:24 Disculpen la demora, selecciono el archivo y al presionar el boton ejecuto esta función que contiene el siguiente código. La clave esta en nombre del archivo en el primer posicion dividido por guion bajo.

    Esto es de prueba cuando funcione voy a recorrer con un while los documentos del zip.

    $ruta = "zip://{$_FILES['archivo']['tmp_name']}";
    $convenio = explode('_', $_FILES['archivo']['name'])[0]; //Aca obtengo la clave del nombre
    $zipobj = new ZipArchive();
    $zipobj->setPassword($convenio);
    $recurso = $zipobj->open($ruta);  // ZipArchive::ER_OPEN
    $zipobj->close();
    
      Votes: 0 - Link answer
     
  • Date: 17-11-2015 03:44:16 Hola hernan ,
    veo que estas haciendo esto

    $zipobj = new ZipArchive();

    quiere decir que tienes una clase ZipArchive();

    pero en tu codigo no veo el inluce o el require de tu archivo que tiene tu clase , si pudieras compartir todo el codigo y llegar a tu solucion , saludos
      Votes: 0 - Link answer
     
  • Date: 17-11-2015 13:05:09 Hola juan te comento estoy cerca de resolver el problema lo tengo en la ruta del archivo, lo que me consultas no es necesario el "include" y el "require" o "require once", porque lo que se habilita es una extension en el php.ini denominada, extension=zip.so y ademas instale con pecl la libreria zip.
    Digo que stoy resolviendo porque estoy realizando otra prueba y funciona correctamente subir el archivo descomrimirlo con zip pero me falta mejorar el codigo nada mas.
    Les agradezco Juan Quinto y Ernesto Peimbert por contestarme y ocupar su tiempo en mi msj.
      Votes: 0 - Link answer
     
  • Date: 20-11-2015 06:05:26 Hola Hernán, según entiendo estas tratando de abrir un archivo zip con password, como dato de color la password es parte del nombre, y el archivo zip es el resultado de un upload (por tal motivo se obtiene del array $_FILES).

    Ahora bien, creo que estas haciendo lo correcto salvo por el orden en el cual estas haciendo la apertura del archivo. Viendo la documentación oficial de la función ZipArchive::setPassword: Establece la contraseña para el archivo activo y observando los ejemplos de apertura de archivos zip con password deduzco que primero debes ejecutar la función ZipArchive::open y luego "setPassword". Veamos un ejemplo:

    <?php
        $zip = new ZipArchive();
        $zip_status = $zip->open("test.zip");
    
        if ($zip_status === true)
        {
            if ($zip->setPassword("MySecretPassword"))
            {
                if (!$zip->extractTo(__DIR__))
                    echo "Extraction failed (wrong password?)";
            }
    
            $zip->close();
        }
        else
        {
            die("Failed opening archive: ". @$zip->getStatusString() . " (code: ". $zip_status .")");
        }
    ?>
    


    Fijate que primero se hace el open() y luego si este da status === true, recien ahí se realiza el "setPassword".

    No estoy 100% seguro que este sea el problema, pero....

    En lo personal, para trabajar con zip suelo utilizar la siguiente librería (un poco más básica, pero no tan dependiente de la configuración del entorno):

     <?php
    class zipfile
    {
        /*
            zipfile class, for reading or writing .zip files
            See http://www.gamingg.net for more of my work
            Based on tutorial given by John Coggeshall at http://www.zend.com/zend/spotlight/creating-zip-files3.php
            Copyright (C) Joshua Townsend and licensed under the GPL
            Version 1.0
        */
        var $datasec = array(); // array to store compressed data
        var $files = array(); // array of uncompressed files
        var $dirs = array(); // array of directories that have been created already
        var $ctrl_dir = array(); // central directory
        var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00"; //end of Central directory record
        var $old_offset = 0;
        var $basedir = ".";
    
        function create_dir($name) // Adds a directory to the zip with the name $name
        {
            $name = str_replace("\\", "/", $name);
    
            $fr = "\x50\x4b\x03\x04";
            $fr .= "\x0a\x00"; // version needed to extract
            $fr .= "\x00\x00"; // general purpose bit flag
            $fr .= "\x00\x00"; // compression method
            $fr .= "\x00\x00\x00\x00"; // last mod time and date
    
            $fr .= pack("V",0); // crc32
            $fr .= pack("V",0); //compressed filesize
            $fr .= pack("V",0); //uncompressed filesize
            $fr .= pack("v",strlen($name)); //length of pathname
            $fr .= pack("v", 0); //extra field length
            $fr .= $name;
            // end of "local file header" segment
    
            // no "file data" segment for path
    
            // "data descriptor" segment (optional but necessary if archive is not served as file)
            $fr .= pack("V",0); //crc32
            $fr .= pack("V",0); //compressed filesize
            $fr .= pack("V",0); //uncompressed filesize
    
            // add this entry to array
            $this->datasec[] = $fr;
    
            $new_offset = strlen(implode("", $this->datasec));
    
            // ext. file attributes mirrors MS-DOS directory attr byte, detailed
            // at http://support.microsoft.com/support/kb/articles/Q125/0/19.asp
    
            // now add to central record
            $cdrec = "\x50\x4b\x01\x02";
            $cdrec .="\x00\x00"; // version made by
            $cdrec .="\x0a\x00"; // version needed to extract
            $cdrec .="\x00\x00"; // general purpose bit flag
            $cdrec .="\x00\x00"; // compression method
            $cdrec .="\x00\x00\x00\x00"; // last mod time and date
            $cdrec .= pack("V",0); // crc32
            $cdrec .= pack("V",0); //compressed filesize
            $cdrec .= pack("V",0); //uncompressed filesize
            $cdrec .= pack("v", strlen($name) ); //length of filename
            $cdrec .= pack("v", 0 ); //extra field length
            $cdrec .= pack("v", 0 ); //file comment length
            $cdrec .= pack("v", 0 ); //disk number start
            $cdrec .= pack("v", 0 ); //internal file attributes
            $cdrec .= pack("V", 16 ); //external file attributes - 'directory' bit set
    
            $cdrec .= pack("V", $this->old_offset); //relative offset of local header
            $this->old_offset = $new_offset;
    
            $cdrec .= $name;
            // optional extra field, file comment goes here
            // save to array
            $this->ctrl_dir[] = $cdrec;
            $this->dirs[] = $name;
        }
    
    
        function create_file($data, $name) // Adds a file to the path specified by $name with the contents $data
        {
            $name = str_replace("\\", "/", $name);
    
            $fr = "\x50\x4b\x03\x04";
            $fr .= "\x14\x00"; // version needed to extract
            $fr .= "\x00\x00"; // general purpose bit flag
            $fr .= "\x08\x00"; // compression method
            $fr .= "\x00\x00\x00\x00"; // last mod time and date
    
            $unc_len = strlen($data);
            $crc = crc32($data);
            $zdata = gzcompress($data);
            $zdata = substr($zdata, 2, -4); // fix crc bug
            $c_len = strlen($zdata);
            $fr .= pack("V",$crc); // crc32
            $fr .= pack("V",$c_len); //compressed filesize
            $fr .= pack("V",$unc_len); //uncompressed filesize
            $fr .= pack("v", strlen($name) ); //length of filename
            $fr .= pack("v", 0 ); //extra field length
            $fr .= $name;
            // end of "local file header" segment
    
            // "file data" segment
            $fr .= $zdata;
    
            // "data descriptor" segment (optional but necessary if archive is not served as file)
            $fr .= pack("V",$crc); // crc32
            $fr .= pack("V",$c_len); // compressed filesize
            $fr .= pack("V",$unc_len); // uncompressed filesize
    
            // add this entry to array
            $this->datasec[] = $fr;
    
            $new_offset = strlen(implode("", $this->datasec));
    
            // now add to central directory record
            $cdrec = "\x50\x4b\x01\x02";
            $cdrec .="\x00\x00"; // version made by
            $cdrec .="\x14\x00"; // version needed to extract
            $cdrec .="\x00\x00"; // general purpose bit flag
            $cdrec .="\x08\x00"; // compression method
            $cdrec .="\x00\x00\x00\x00"; // last mod time & date
            $cdrec .= pack("V",$crc); // crc32
            $cdrec .= pack("V",$c_len); //compressed filesize
            $cdrec .= pack("V",$unc_len); //uncompressed filesize
            $cdrec .= pack("v", strlen($name) ); //length of filename
            $cdrec .= pack("v", 0 ); //extra field length
            $cdrec .= pack("v", 0 ); //file comment length
            $cdrec .= pack("v", 0 ); //disk number start
            $cdrec .= pack("v", 0 ); //internal file attributes
            $cdrec .= pack("V", 32 ); //external file attributes - 'archive' bit set
    
            $cdrec .= pack("V", $this->old_offset); //relative offset of local header
            $this->old_offset = $new_offset;
    
            $cdrec .= $name;
            // optional extra field, file comment goes here
            // save to central directory
            $this->ctrl_dir[] = $cdrec;
        }
    
        function read_zip($name)
        {
            // Clear current file
            $this->datasec = array();
    
            // File information
            $this->name = $name;
            $this->mtime = filemtime($name);
            $this->size = filesize($name);
    
            // Read file
            $fh = fopen($name, "rb");
            $filedata = fread($fh, $this->size);
            fclose($fh);
    
            // Break into sections
            $filesecta = explode("\x50\x4b\x05\x06", $filedata);
    
            // ZIP Comment
            $unpackeda = unpack('x16/v1length', $filesecta[1]);
            $this->comment = substr($filesecta[1], 18, $unpackeda['length']);
            $this->comment = str_replace(array("\r\n", "\r"), "\n", $this->comment); // CR + LF and CR -> LF
    
            // Cut entries from the central directory
            $filesecta = explode("\x50\x4b\x01\x02", $filedata);
            $filesecta = explode("\x50\x4b\x03\x04", $filesecta[0]);
            array_shift($filesecta); // Removes empty entry/signature
    
            foreach($filesecta as $filedata)
            {
                // CRC:crc, FD:file date, FT: file time, CM: compression method, GPF: general purpose flag, VN: version needed, CS: compressed size, UCS: uncompressed size, FNL: filename length
                $entrya = array();
                $entrya['error'] = "";
    
                $unpackeda = unpack("v1version/v1general_purpose/v1compress_method/v1file_time/v1file_date/V1crc/V1size_compressed/V1size_uncompressed/v1filename_length", $filedata);
    
                // Check for encryption
                $isencrypted = (($unpackeda['general_purpose'] & 0x0001) ? true : false);
    
                // Check for value block after compressed data
                if($unpackeda['general_purpose'] & 0x0008)
                {
                    $unpackeda2 = unpack("V1crc/V1size_compressed/V1size_uncompressed", substr($filedata, -12));
    
                    $unpackeda['crc'] = $unpackeda2['crc'];
                    $unpackeda['size_compressed'] = $unpackeda2['size_uncompressed'];
                    $unpackeda['size_uncompressed'] = $unpackeda2['size_uncompressed'];
    
                    unset($unpackeda2);
                }
    
                $entrya['name'] = substr($filedata, 26, $unpackeda['filename_length']);
    
                if(substr($entrya['name'], -1) == "/") // skip directories
                {
                    continue;
                }
    
                $entrya['dir'] = dirname($entrya['name']);
                $entrya['dir'] = ($entrya['dir'] == "." ? "" : $entrya['dir']);
                $entrya['name'] = basename($entrya['name']);
    
    
                $filedata = substr($filedata, 26 + $unpackeda['filename_length']);
    
                if(strlen($filedata) != $unpackeda['size_compressed'])
                {
                    $entrya['error'] = "Compressed size is not equal to the value given in header.";
                }
    
                if($isencrypted)
                {
                    $entrya['error'] = "Encryption is not supported.";
                }
                else
                {
                    switch($unpackeda['compress_method'])
                    {
                        case 0: // Stored
                            // Not compressed, continue
                        break;
                        case 8: // Deflated
                            $filedata = gzinflate($filedata);
                        break;
                        case 12: // BZIP2
                            if(!extension_loaded("bz2"))
                            {
                                @dl((strtolower(substr(PHP_OS, 0, 3)) == "win") ? "php_bz2.dll" : "bz2.so");
                            }
    
                            if(extension_loaded("bz2"))
                            {
                                $filedata = bzdecompress($filedata);
                            }
                            else
                            {
                                $entrya['error'] = "Required BZIP2 Extension not available.";
                            }
                        break;
                        default:
                            $entrya['error'] = "Compression method ({$unpackeda['compress_method']}) not supported.";
                    }
    
                    if(!$entrya['error'])
                    {
                        if($filedata === false)
                        {
                            $entrya['error'] = "Decompression failed.";
                        }
                        elseif(strlen($filedata) != $unpackeda['size_uncompressed'])
                        {
                            $entrya['error'] = "File size is not equal to the value given in header.";
                        }
                        elseif(crc32($filedata) != $unpackeda['crc'])
                        {
                            $entrya['error'] = "CRC32 checksum is not equal to the value given in header.";
                        }
                    }
    
                    $entrya['filemtime'] = mktime(($unpackeda['file_time'] & 0xf800) >> 11,($unpackeda['file_time'] & 0x07e0) >> 5, ($unpackeda['file_time'] & 0x001f) << 1, ($unpackeda['file_date'] & 0x01e0) >> 5, ($unpackeda['file_date'] & 0x001f), (($unpackeda['file_date'] & 0xfe00) >> 9) + 1980);
                    $entrya['data'] = $filedata;
                }
    
                $this->files[] = $entrya;
            }
    
            return $this->files;
        }
    
        function add_file($file, $dir = ".", $file_blacklist = array(), $ext_blacklist = array())
        {
            $file = str_replace("\\", "/", $file);
            $dir = str_replace("\\", "/", $dir);
    
            if(strpos($file, "/") !== false)
            {
                $dira = explode("/", "{$dir}/{$file}");
                $file = array_shift($dira);
                $dir = implode("/", $dira);
                unset($dira);
            }
    
            while(substr($dir, 0, 2) == "./")
            {
                $dir = substr($dir, 2);
            }
            while(substr($file, 0, 2) == "./")
            {
                $file = substr($file, 2);
            }
            if(!in_array($dir, $this->dirs))
            {
                if($dir == ".")
                {
                    $this->create_dir("./");
                }
                $this->dirs[] = $dir;
            }
            if(in_array($file, $file_blacklist))
            {
                return true;
            }
            foreach($ext_blacklist as $ext)
            {
                if(substr($file, -1 - strlen($ext)) == ".{$ext}")
                {
                    return true;
                }
            }
    
            $filepath = (($dir && $dir != ".") ? "{$dir}/" : "").$file;
            if(is_dir("{$this->basedir}/{$filepath}"))
            {
                $dh = opendir("{$this->basedir}/{$filepath}");
                while(($subfile = readdir($dh)) !== false)
                {
                    if($subfile != "." && $subfile != "..")
                    {
                        $this->add_file($subfile, $filepath, $file_blacklist, $ext_blacklist);
                    }
                }
                closedir($dh);
            }
            else
            {
                $this->create_file(implode("", file("{$this->basedir}/{$filepath}")), $filepath);
            }
    
            return true;
        }
    
    
        function zipped_file() // return zipped file contents
        {
            $data = implode("", $this->datasec);
            $ctrldir = implode("", $this->ctrl_dir);
    
            return $data.
                    $ctrldir.
                    $this->eof_ctrl_dir.
                    pack("v", sizeof($this->ctrl_dir)). // total number of entries "on this disk"
                    pack("v", sizeof($this->ctrl_dir)). // total number of entries overall
                    pack("V", strlen($ctrldir)). // size of central dir
                    pack("V", strlen($data)). // offset to start of central dir
                    "\x00\x00"; // .zip file comment length
        }
    }
    ?> 
    


    Fuente de la clase

    Saludos,
    Fernando
      Votes: 0 - Link answer
     
To actively participate in the community first must authenticate, enter the system.Sign In