web-dev-qa-db-fra.com

Avertissement sur ZipArchive Fermer

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:

  1. Si aucun fichier réel n'est ajouté au Zip, depuis PHP 5.6 - cela pourrait être une explication probable depuis que j'ai récemment mis à niveau vers PHP 5.6. Cependant:
    • Je vérifie que chaque fichier existe avant de l'ajouter
    • J'ai essayé d'ajouter un fichier texte factice non vide au Zip. L'ajouter au Zip renvoie true, tout comme file_exists() sur le fichier
    • Quand je fais écho à $Zip->numFiles Et qu'il donne un nombre d'au moins 1 (lorsque le Zip n'a pas de fichiers sauf le mannequin)
  2. Si le répertoire dans lequel le Zip doit être écrit n'existe pas ou n'a pas les bonnes autorisations: cela ne semble pas être le cas, mais juste pour être sûr, j'ai écrit un fichier texte dans le même dossier dans le même script et il n'y avait pas de problème
  3. En cas de problème d'écriture dans le répertoire temporaire. C'est un peu plus difficile à vérifier, mais j'ai un script de téléchargement dans le même système qui fonctionne, et je me suis assuré qu'il n'y avait pas de problèmes d'espace disque, etc.

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
13
Ynhockey

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.

13
Ynhockey