2016-05-18 15 views
5

Sto cercando di risolvere un problema in uno script di auto-zip per alcune immagini, che ho scritto qualche tempo fa e che ha funzionato fino ad ora. Tutto sembra bene fino $zip->close(); che ha pronunciato la seguente:Avviso su ZipArchive Chiudi

<b>Warning</b>: ZipArchive::close(): Read error: No such file or directory in <b></b> on line <b>287</b><br /> 

ho letto i documenti e alcuni forum e ho scoperto che questo possa accadere in uno dei seguenti scenari:

  1. Se non vengono aggiunti file effettivi allo zip, da PHP 5.6-questa potrebbe essere una probabile spiegazione dato che ho recentemente aggiornato a PHP 5.6. Tuttavia:
    • verifico che ogni file esistente prima di aggiungerlo
    • ho cercato di aggiungere un file di testo non vuoto fittizio per la zip. Aggiungendo alla zip restituisce true, come fa file_exists() sul file
    • Quando mi associo $zip->numFiles e dà una serie di almeno 1 (quando la zip ha nessun file, tranne il fittizio)
  2. Se la directory al punto in cui lo zip deve essere scritto non esiste o non ha i permessi giusti: questo non sembra essere il caso, ma per sicurezza, ho scritto un file di testo nella stessa cartella nello stesso script e non si sono verificati problemi
  3. Se si verifica un problema durante la scrittura nella directory temporanea. È un po 'più difficile da controllare, ma ho uno script di caricamento nello stesso sistema che funziona, e ho assicurato che non ci siano problemi di spazio su disco ecc.

Ecco il codice relativo. Alcune variabili sono definite in anticipo. Nota che scrivo ogni problema sul mio log, e questo script non genera alcuna voce!

$zip_file = 'Project'.$project_id.'.zip'; 
$zip = new ZipArchive; 
if ($zip_result = $zip->open($zip_path.'/'.$zip_file, ZIPARCHIVE::CREATE) !== true) { 
    echo 'Error creating zip for project: '.$project_id.'. Error code: '.$zip_result; 
    help::debugLog('Error creating zip for project: '.$project_id.'. Error code: '.$zip_result); 
    return false; 
} 
$file_list = array(); 

foreach ($item_thumbs as $item) 
{ 
    $full_thumb_path = $thumb_dir.'/'.$item['thumb']; 
    if (file_exists($full_thumb_path) and $item['thumb']) 
    { 
     $file_added = $zip->addFile($full_thumb_path, basename($item['thumb'])); 
     if (!$file_added) 
      help::debugLog('Failed to add item thumb to project zip. Project: '.$project_id.', file name: '.$item['thumb']); 
     else 
      $file_list[] = $item['thumb']; 
    } 
    elseif ($item['thumb']) /* If thumb indicated in DB doesn't exist in file system */ 
     help::debugLog('Item thumb file '.$item['thumb'].' from item: '.$item['id'].' is missing from its indended location: '.$full_thumb_path); 
} 

/* Added 2016-05-18 -- creates dummy file for the zip listing its contents, important in case zip is empty */ 
$file_list_path = $zip_path.'/file_list.txt'; 
if (!($file_list_file = fopen($file_list_path, 'w+'))) 
    help::debugLog('Failed to create list file (intended for zip) for project: '.$project_id); 
fwrite($file_list_file, "File list:\n"); 
fwrite($file_list_file, implode("\n", $file_list)); 
if (file_exists($file_list_path)) 
{ 
    fclose($file_list_file); 
    if (!$zip->addFile($file_list_path)) 
     help::debugLog('Failed to add list file to project zip for project: '.$project_id); 
    unlink($file_list_path); 
} 
else 
    help::debugLog('Failed to create list file (intended for zip) for project: '.$project_id); 

$zip->close(); // line 287 

risposta

6

'venuto fuori che la soluzione era molto semplice, e in realtà di cui la documentazione (php.net), in uno dei commenti:

It may seem a little obvious to some but it was an oversight on my behalf.

If you are adding files to the zip file that you want to be deleted make sure you delete AFTER you call the close() function.

If the files added to the object aren't available at save time the zip file will not be created.

Quindi, dal mio codice di cui sopra, la " "fittizio" il file di testo viene eliminato prima che lo zip venga chiuso, facendo necessariamente in modo che il file non esista al momento della creazione dello zip.

Avevo buone ragioni per ritenere che lo zip sia stato creato in una posizione temporanea e solo spostato nella posizione finale su close(). Risulta che questo non è il caso.

+2

Quindi, come sei riuscito a risolvere il problema nel tuo codice? – Grigio

+0

Ho spostato $ zip-> close() in un punto prima che il file di testo venga eliminato. – Ynhockey

-1

Controllare il valore di "$ full_thumb_path" nella riga

$file_added = $zip->addFile($full_thumb_path, basename($item['thumb'])); 

Il valore deve essere un percorso di file e non deve essere un percorso di directory.

+0

Anche se si tratta di una directory, non darebbe un avviso su zip_close() in questo script, se il file fittizio non viene cancellato. – Ynhockey

+0

Ho appena avuto questo durante una build di phing. Il messaggio: [Errore PHP] ZipArchive :: close(): errore di lettura: è una directory -> la risposta è semplice, è solo perché c'era un * collegamento simbolico * nell'albero dei file – Nadir