2016-05-18 19 views
5

Próbuję naprawić problem w auto-zipie dla niektórych obrazów, które napisałem jakiś czas temu i działały do ​​tej pory. Wszystko wydaje się w porządku, dopóki $zip->close(); co daje następujące:Ostrzeżenie dotyczące ZipArchive Close

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

Czytam docs i niektóre fora i okazało się, że to może się zdarzyć w jednym z następujących scenariuszy:

  1. Jeśli nie rzeczywiste pliki są dodawane do kodu zip, od PHP 5.6 - może to być prawdopodobne wyjaśnienie, odkąd ostatnio uaktualniono do PHP 5.6. Jednakże:
    • sprawdzić, że każdy plik istnieje przed dodaniem go
    • Próbowałem dodać obojętne niepusty plik tekstowy na zamek błyskawiczny. Dodanie go do zip zwraca true, tak jak file_exists() plik
    • Kiedy echo $zip->numFiles i daje liczbę co najmniej 1 (gdy zip ma pliki z wyjątkiem manekina)
  2. Jeśli katalog tam, gdzie musi być zapisany zip, nie istnieje lub nie ma odpowiednich uprawnień: To się nie wydarzyło, ale dla pewności napisałem plik tekstowy do tego samego folderu w tym samym skrypcie i nie było problemu
  3. Jeśli wystąpił problem z zapisem w katalogu temp. Trochę trudniej to sprawdzić, ale mam skrypt do przesłania w tym samym systemie, który działa, i upewniłem się, że nie ma problemów z miejscem na dysku itp.

Oto odpowiedni kod. Niektóre zmienne są zdefiniowane wcześniej. Zauważ, że piszę każdy problem do mojego logu, a ten skrypt nie generuje żadnych wpisów!

$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 

Odpowiedz

6

Okazuje się, że rozwiązanie jest bardzo proste, a to faktycznie, o których mowa w docs (php.net), w jednym z komentarzy:

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.

Tak od mojego kodu powyżej, w " dummy "plik tekstowy jest usuwany przed zamknięciem zip, koniecznie czyniąc go tym, że plik nie istnieje w momencie tworzenia zip.

Miałem powody, by sądzić, że zip został utworzony w tymczasowej lokalizacji i przeniesiony do ostatecznej lokalizacji na close(). Okazuje się, że tak nie jest.

+2

Jak udało się rozwiązać problem w kodzie? – Grigio

+0

Przesunąłem $ zip-> close() do punktu, zanim plik tekstowy zostanie usunięty. – Ynhockey

-1

Sprawdź wartość „$ full_thumb_path” w linii

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

Wartość powinna być ścieżka do pliku i nie musi być ścieżka do katalogu.

+0

Nawet jeśli jest to katalog, to nie daje ostrzeżenia na zip_close() w tym skrypcie, jeśli plik dummy nie zostanie usunięty. – Ynhockey

+0

Po prostu miałem to podczas kompilacji phing. Komunikat: [Błąd PHP] ZipArchive :: close(): Błąd odczytu: Czy katalog -> odpowiedź jest prosta, to dlatego, że w drzewie plików było jakieś * symboliczne łącze * – Nadir

Powiązane problemy