[RESOLU] Créer fichier zip par ajax

Eléphant du PHP | 385 Messages

12 juil. 2016, 14:22

Bonjour à tous, pourriez-vous m'aider?

Voilà j'essaye de créer un zip puis de le télécharger sur le poste client

j'ai donc ça

Code : Tout sélectionner

<?php if(!isset($_GET['id_dm'])) exit; include("../../../../connexion.php"); $req_dm = "SELECT NUM_AFFAIRE FROM POP_DM WHERE ID_DM= ".$_GET['id_dm']; $sta_dm = oci_parse($conn, $req_dm); oci_execute($sta_dm,OCI_COMMIT_ON_SUCCESS); $info = oci_fetch_assoc($sta_dm); $zip = new ZipArchive; $file = 'Documents_affaire'.$info['NUM_AFFAIRE'].'.zip'; $res = $zip->open($file, ZipArchive::CREATE); $req_fichier = "SELECT ID_FICHIER_DM,LABEL_FICHIER_DM FROM POP_FICHIER_DM WHERE ID_DM = ".$_GET['id_dm'].""; $sta_fichier = oci_parse($conn, $req_fichier); oci_execute($sta_fichier,OCI_COMMIT_ON_SUCCESS); while($fichier= oci_fetch_assoc($sta_fichier)) { $zip->addFromString($fichier['LABEL_FICHIER_DM'], $fichier['ID_FICHIER_DM']); } $zip->close(); if (file_exists($file)) { header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="'.basename($file).'"'); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); header('Content-Length: ' . filesize($file)); readfile($file); exit; } ?>
Mon zip est bien crée mais je voudrais qu'il soit automatiquement téléchargé puis supprimé, mais les header ne fonctionne pas avez-vous une idée? merci à vous

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

12 juil. 2016, 15:06

salut,

il se passe quoi si tu appels directement ce fichier dans ton navigateur ?
a priori cela semble correcte.
Perso je ferais 2 - 3 modifs
header('Pragma: no-cache');
header('Content-Type: application/zip');

Pense à ajouter un oci_free_statement($sta_fichier); après le while. (et un oci_close() en fin de fichier).

@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 385 Messages

12 juil. 2016, 15:46

Merci pour votre aide ,

Si je test dans un script indépendant avec directement

Code : Tout sélectionner

<?php $file = 'Documents_affaireC0264-BX158-002.zip'; if (file_exists($file)) { header('Content-Description: File Transfer'); header('Content-Type: application/zip'); header('Content-Disposition: attachment; filename="'.basename($file).'"'); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: no-cache'); header('Content-Length: ' . filesize($file)); readfile($file); exit; } ?>
je télécharge bien le zip.

Mais la j'ai un bouton qui appelle une fonction javascript puis un script php qui enregistre mon zip cela fonctionne, mais après le téléchargement ne passe pas, par contre si je m'est des données bidon et je teste mon script indépendamment dans le navigateur j'ai bien un téléchargement.

script principal -> fonction javascript -> script php externe qui enregistre et doit forcer le téléchargement.

voici le script php indépendant tout fonctionne sauf le téléchargement

Code : Tout sélectionner

<?php if(!isset($_GET['id_dm'])) exit; include("../../../../connexion.php"); // Requete pour renvoyer l'étape à laquel se trouve la HP $req_dm = "SELECT NUM_AFFAIRE FROM POP_DM WHERE ID_DM= ".$_GET['id_dm']; $sta_dm = oci_parse($conn, $req_dm); oci_execute($sta_dm,OCI_COMMIT_ON_SUCCESS); $info = oci_fetch_assoc($sta_dm); $zip = new ZipArchive; $file = 'Documents_affaire'.$info['NUM_AFFAIRE'].'.zip'; $res = $zip->open($file, ZipArchive::CREATE); $req_fichier = "SELECT ID_FICHIER_DM,LABEL_FICHIER_DM FROM POP_FICHIER_DM WHERE ID_DM = ".$_GET['id_dm'].""; $sta_fichier = oci_parse($conn, $req_fichier); oci_execute($sta_fichier,OCI_COMMIT_ON_SUCCESS); while($fichier= oci_fetch_assoc($sta_fichier)) { $zip->addFromString($fichier['LABEL_FICHIER_DM'], $fichier['ID_FICHIER_DM']); } oci_free_statement($sta_fichier); $zip->close(); if (file_exists($file)) { header('Content-Description: File Transfer'); header('Content-Type: application/zip'); header('Content-Disposition: attachment; filename="'.basename($file).'"'); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: no-cache'); header('Content-Length: ' . filesize($file)); readfile($file); exit; } ?>
Autre problème le zip fait 1kb les fichiers ne contiennent que le nom. Merci de votre aide

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

12 juil. 2016, 16:56

comme ça ce n'est pas possible.

il y a une info la : http://stackoverflow.com/questions/5192 ... s-or-query

et un script js pour te permettre de simuler la chose ici

il est peux être possible de le faire aussi en utilisant une iframe cachée pour cible de ton script.

@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 385 Messages

12 juil. 2016, 20:06

Ce que je veux c'est quand la personne clique sur un bouton elle récupère les fichier de la base de données sous forme de zip puis après cela le fichier zip est supprimé du serveur. Je ne vois pas comment utiliser ce que vous m'avez donné, en javascript je ne peux sélectionner qu'un fichier côté client. Mon zip ne fonctionne pas il fait un kb même sur le serveur. Pourriez vous m'expliquer s'il vous plaît? Je vous remercie.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

13 juil. 2016, 09:46

c'est juste pas possible de forcer un dl qu'un client n'as pas souhaiter (imagine les merdes qui seraient poussées sur ton ordi sur chaque page).

Le plus simple c'est de virer l'action JS et d'utiliser un formulaire classique dont la cible génère le zip et le pousse ensuite au client.
pour supprimer coté serveur c'est avant le exit() avec la fonction unlink

@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 385 Messages

13 juil. 2016, 10:12

Merci, par contre pour créer le zip j'ai quelque soucis voici mon script

Code : Tout sélectionner

$zip = new ZipArchive; $file = 'Documents_affaire'.$info['NUM_AFFAIRE'].'.zip'; $res = $zip->open($file, ZipArchive::CREATE); $req_fichier = "SELECT * FROM POP_FICHIER_DM WHERE ID_DM = ".$_GET['id_dm'].""; $sta_fichier = oci_parse($conn, $req_fichier); oci_execute($sta_fichier,OCI_COMMIT_ON_SUCCESS); while($fichier= oci_fetch_assoc($sta_fichier)) { $requete4 = "SELECT TYPE_FICHIER_DM,FICHIER_DM,LABEL_FICHIER_DM FROM POP_FICHIER_DM WHERE ID_FICHIER_DM = ".$fichier['ID_FICHIER_DM']; $statement4 = oci_parse($conn, $requete4); oci_execute($statement4,OCI_COMMIT_ON_SUCCESS); $list4 = oci_fetch_assoc($statement4); $fichier = $list4['FICHIER_DM']->load(); $zip->addFromString($fichier['LABEL_FICHIER_DM'], $fichier); } $zip->close();
je ne passe plus par ajax, par contre cela me génère des fichiers avec comme nom %, ë et ï. Les fichiers non pas l'extension juste un type file mais il contient bien les données. merci

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

13 juil. 2016, 14:10

déjà tu écrases ta variable fichier en cours de route du coup le nom n'est pas ce que tu attends.
Il faut éviter de réutiliser des variables comme ça.

ensuite fair eune requête dans un while c'est pas une bonne idée.
Si vraiment tu n'as pas le choix alors tu utilises une requête préparée pour améliorer les performances.
http://php.net/manual/fr/function.oci-bind-by-name.php
http://php.net/manual/en/oci8.examples.php#example-2184

Pour info OCI_COMMIT_ON_SUCCESS c'est la valeur par défaut d'un oci_execute et surtout cela n'a ps de sens sur un select (y a pas de commit à faire ;) ).


du coup on se retrouve avec un truc dans le genre (sans les problèmes de syntaxe)
<?php
$zip = new ZipArchive();
$file = 'Documents_affaire'.$info['NUM_AFFAIRE'].'.zip';
$res = $zip->open($file, ZipArchive::CREATE);

$req_fichier = 'SELECT TYPE_FICHIER_DM,FICHIER_DM,LABEL_FICHIER_DM
   FROM POP_FICHIER_DM
   WHERE ID_FICHIER_DM in(SELECT ID_FICHIER_DM FROM POP_FICHIER_DM WHERE ID_DM = :iddm)';
$stmt = oci_parse($conn, $req_fichier);
oci_bind_by_name($stmt,':iddm', $_GET['id_dm'],OCI_B_INT);
oci_execute($stmt);
while($fichier= oci_fetch_assoc($stmt,OCI_ASSOC+OCI_RETURN_LOBS))
{
    $zip->addFromString($fichier['LABEL_FICHIER_DM'], $fichier['FICHIER_DM']);
}

$zip->close();
oci_free_statement($stmt);
@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 385 Messages

13 juil. 2016, 14:59

J'ai réussis

Code : Tout sélectionner

$zip = new ZipArchive; $file = $info['NUM_AFFAIRE'].'.zip'; $res = $zip->open($file, ZipArchive::CREATE); $req_fichier = "SELECT * FROM POP_FICHIER_DM WHERE ID_DM = :iddm"; $stmt = oci_parse($conn, $req_fichier); oci_bind_by_name($stmt,':iddm', $_GET['id_dm'],OCI_B_INT); oci_execute($stmt); while($fichier= oci_fetch_assoc($stmt)) { $requete4 = "SELECT TYPE_FICHIER_DM,FICHIER_DM,LABEL_FICHIER_DM FROM POP_FICHIER_DM WHERE ID_FICHIER_DM = ".$fichier['ID_FICHIER_DM']; $statement4 = oci_parse($conn, $requete4); oci_execute($statement4,OCI_COMMIT_ON_SUCCESS); $list4 = oci_fetch_assoc($statement4); $fichier_data = $list4['FICHIER_DM']->load(); $zip->addFromString($fichier['LABEL_FICHIER_DM'], $fichier_data); } $zip->close(); oci_free_statement($stmt);
Avec votre méthode le zip ne se créer pas, merci de votre aide.