J'essaie de résoudre un problème dans un script auto-Zip pour certaines images, que j'ai écrit il y a quelque temps et qui a fonctionné jusqu'à présent. Tout semble bien jusqu'à $Zip->close();
ce qui donne ce qui suit:
<b>Warning</b>: ZipArchive::close(): Read error: No such file or directory in <b></b> on line <b>287</b><br />
J'ai lu les documents et certains forums et j'ai découvert que cela pouvait se produire dans l'un des scénarios suivants:
file_exists()
sur le fichier$Zip->numFiles
Et qu'il donne un nombre d'au moins 1 (lorsque le Zip n'a pas de fichiers sauf le mannequin)Voici le code pertinent. Certaines variables sont définies au préalable. Notez que j'écris chaque problème dans mon journal et que ce script ne génère aucune entrée!
$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
Il s'avère que la solution était très simple, et elle est en fait mentionnée dans la documentation (php.net), dans l'un des commentaires:
Cela peut sembler un peu évident pour certains, mais c'était un oubli de ma part.
Si vous ajoutez des fichiers au fichier Zip que vous souhaitez supprimer, assurez-vous de les supprimer APRÈS avoir appelé la fonction close ().
Si les fichiers ajoutés à l'objet ne sont pas disponibles au moment de la sauvegarde, le fichier Zip ne sera pas créé.
(Source: https://www.php.net/manual/en/ziparchive.close.php#93322 )
Donc, à partir de mon code ci-dessus, le fichier texte "factice" est supprimé avant la fermeture du Zip, ce qui fait nécessairement que le fichier n'existe pas au moment de la création du Zip.
J'avais de bonnes raisons de croire que le Zip a été créé dans un emplacement temporaire et déplacé uniquement vers l'emplacement final sur close()
. Il s'avère que ce n'est pas le cas.