[PHP] Barre de progression d'upload
Dernière réponse : dans Programmation
Bonjour,
je travaille actuellement sur une barre de progression d'upload de fichiers en PHP avec APC.
J'ai suivi la méthode décrite par de nombreux tutos (par exemple, http://www.miasmatech.net/scripts/article/article_conte...),
et j'ai beau retourner le problème dans tous les sens, j'arrive toujours à la situation suivante :
quand je fais un apc_fetch(key), ca me renvoie toujours false tant que l'upload n'est pas terminé... mais une fois l'upload terminé, ca me renvoie bien les informations sur l'upload... ce qui ne m'avance pas pour faire une barre de progression.
Quelqu'un a une idée de l'origine du problème ?
Merci d'avance
Christophe
je travaille actuellement sur une barre de progression d'upload de fichiers en PHP avec APC.
J'ai suivi la méthode décrite par de nombreux tutos (par exemple, http://www.miasmatech.net/scripts/article/article_conte...),
et j'ai beau retourner le problème dans tous les sens, j'arrive toujours à la situation suivante :
quand je fais un apc_fetch(key), ca me renvoie toujours false tant que l'upload n'est pas terminé... mais une fois l'upload terminé, ca me renvoie bien les informations sur l'upload... ce qui ne m'avance pas pour faire une barre de progression.
Quelqu'un a une idée de l'origine du problème ?
Merci d'avance
Christophe
Autres pages sur : php barre progression upload
Lassé par la pub ? Créez un compte
L'extension APC, par activation de la RFC1867, permet effectivement de connaître l'avancement de l'upload d'un fichier.
(Voir par exemple la doc : http://php.net/manual/fr/apc.configuration.php )
L'affichage d'un loading ne me suffit pas, étant donné qu'il s'agira de gros fichiers.
Une barre de progression est nécessaire pour améliorer la qualité de service.
(Voir par exemple la doc : http://php.net/manual/fr/apc.configuration.php )
L'affichage d'un loading ne me suffit pas, étant donné qu'il s'agira de gros fichiers.
Une barre de progression est nécessaire pour améliorer la qualité de service.
Salut OmaR,
Comme je l'ai mis dans mon post, la fonction apc_fetch renvoie bien un tableau sur l'avancement, mais uniquement une fois l'upload terminé.
Pendant l'upload, elle renvoie false, comme si la clé APC_UPLOAD_PROGRESS insérée dans le formulaire n'existait pas encore du point de vue d'APC.
Donc oui, la version de PHP est correcte et APC est bien installé.
Quant à savoir si tout est bien configuré... j'ai regardé le maximum de configuration pour APC dans le php.ini et ai l'impression que tout est bien configuré, mais je ne peux pas dire que c'est le cas à 100%...
Comme je l'ai mis dans mon post, la fonction apc_fetch renvoie bien un tableau sur l'avancement, mais uniquement une fois l'upload terminé.
Pendant l'upload, elle renvoie false, comme si la clé APC_UPLOAD_PROGRESS insérée dans le formulaire n'existait pas encore du point de vue d'APC.
Donc oui, la version de PHP est correcte et APC est bien installé.
Quant à savoir si tout est bien configuré... j'ai regardé le maximum de configuration pour APC dans le php.ini et ai l'impression que tout est bien configuré, mais je ne peux pas dire que c'est le cas à 100%...
Alors, pour le code du formulaire :
A savoir que la fonction submitVideo valide le formulaire avec jQuery / ajaxForm.
Et que côté serveur, pendant l'upload de la vidéo, je lance juste un apc_fetch avec la bonne clé pour voir l'avancement de l'upload... j'utilise la bonne clé, il n'y a (normalement) aucun doute à ce sujet.
Quoiqu'il en soit, merci de m'accorder un peu de ton temps.
<form id="formId" method="post" action="/formValid" enctype="multipart/form-data">
<table class="tablewhite">
<tr>
<td colspan='2' class='title'>Nom du fichier</td>
</tr>
<tr>
<td><input name="textField" value="" /></td>
</tr>
<tr>
<td>Votre fichier</td>
<td class="element">
<input type="hidden" name="APC_UPLOAD_PROGRESS" id="progress_key" value="<? echo $progressKey; ?>"/>
<input id="file" type="file" name="file" />
</td>
</tr>
<tr id="submitTr">
<td colspan="2" class="center">
<input type="button" value="Envoyer" onclick="submitVideo();" />
<input type="hidden" name="MAX_FILE_SIZE" value="2147483648">
</td>
</tr>
</table>
</form>
A savoir que la fonction submitVideo valide le formulaire avec jQuery / ajaxForm.
Et que côté serveur, pendant l'upload de la vidéo, je lance juste un apc_fetch avec la bonne clé pour voir l'avancement de l'upload... j'utilise la bonne clé, il n'y a (normalement) aucun doute à ce sujet.
Quoiqu'il en soit, merci de m'accorder un peu de ton temps.
Oui c'est ca, je renvoie une requête avec cette clé unique en paramètre, vers une action qui doit juste me renvoyer l'avancement.
On dirait que le comportement que j'ai actuellement, est celui que j'aurais eu si j'avais mis dans le formulaire la clé après le champ file. C'est-à-dire que dans l'ordre des paramètres envoyés à la validation du formulaire, il enverrait d'abord le fichier, puis la clé, ce qui fait que tant que le fichier n'est pas uploadé, APC n'a pas créé le fichier d'avancement de l'upload.
J'ai pensé que cela pouvait être dû au fonctionnement d'ajaxForm, puisque pour valider un formulaire d'upload en "ajax", je suppose qu'il recrée une iframe d'1px avec le formulaire à l'intérieur, et que du coup il se pourrait qu'il modifie l'ordre des paramètres.
Mais j'ai toujours le problème quand je fais un simple formulaire sans ajax...
Donc là je suis vraiment dans l'impasse...
On dirait que le comportement que j'ai actuellement, est celui que j'aurais eu si j'avais mis dans le formulaire la clé après le champ file. C'est-à-dire que dans l'ordre des paramètres envoyés à la validation du formulaire, il enverrait d'abord le fichier, puis la clé, ce qui fait que tant que le fichier n'est pas uploadé, APC n'a pas créé le fichier d'avancement de l'upload.
J'ai pensé que cela pouvait être dû au fonctionnement d'ajaxForm, puisque pour valider un formulaire d'upload en "ajax", je suppose qu'il recrée une iframe d'1px avec le formulaire à l'intérieur, et que du coup il se pourrait qu'il modifie l'ordre des paramètres.
Mais j'ai toujours le problème quand je fais un simple formulaire sans ajax...
Donc là je suis vraiment dans l'impasse...
Voilà le code JS :
var progressKey = <? echo $progressKey; ?>;
function submitVideo() {
$("#formId").ajaxSubmit({
dataType: "json",
success: callbackUploadFile
});
}
function callbackUploadFile(data) {
if (data.success == false) {
// Affichage des erreurs
/* ... */
} else {
getUploadProgress();
}
}
function getUploadProgress() {
$.ajax({
url: "/progress/key/" + progressKey,
async: true,
success: function(data) {
// Update de la barre d'avancement
/* ... */
}
});
if (upload non terminé) {
setTimeout("getUploadProgress()", 1000);
}
}
Si tu utilises Firefox, installe Firebug si tu ne l'as pas déjà.
Ensuite, quand tu valides ton formulaire, regarde dans l'onglet Réseau de Firebug que les appels Ajax sont bien faits, et qu'ils ont les bonnes données.
Tu pourras vérifier la requête et la réponse.
Ensuite, quand tu valides ton formulaire, regarde dans l'onglet Réseau de Firebug que les appels Ajax sont bien faits, et qu'ils ont les bonnes données.
Tu pourras vérifier la requête et la réponse.
Regarde là, commentaire n°9 (zounounous).
Ca pourra peut-être t'aider -> pas de barre de progression si apc tourne en CGI / Fast CGI.
Ca pourra peut-être t'aider -> pas de barre de progression si apc tourne en CGI / Fast CGI.
Je suis loin d'être un expert, mais juste une proposition car je ne vois pas dans ton code l'endroit où tu vas récupérer l'état d'avancement de l'upload, est-ce que tu fais bien précéder d'id du fichier en chargement par le préfixe (par défaut "upload_") ?
Le tuto dont tu fais mention au début du topic en parles mais franchement (et c'est profane qui dit ça
) le tuto en question me parait bien compliqué pour le sujet qu'il aborde...
Si tu fais un simple "copier / coller" d'un fichier source sur ton serveur, est-ce que ça marche ?
Genre le formulaire .php que tu appels comme tu veux :
Le javascript apc.js :
Et le fichier php "verifUpload.php" qui récupère l'état d'avancement :
Le tout sur ton serveur, au même niveau de l'arborescence, ça donne quoi ? (ça devrait être ça)
Le tuto dont tu fais mention au début du topic en parles mais franchement (et c'est profane qui dit ça
) le tuto en question me parait bien compliqué pour le sujet qu'il aborde...Si tu fais un simple "copier / coller" d'un fichier source sur ton serveur, est-ce que ça marche ?
Genre le formulaire .php que tu appels comme tu veux :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "<a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" target="_blank">http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd</a>">
<html xmlns="<a href="http://www.w3.org/1999/xhtml" target="_blank">http://www.w3.org/1999/xhtml</a>" xml:lang="fr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>APC - Upload simple (par Nesquik69)</title>
<script type="text/javascript" src="apc.js"></script>
<style type="text/css">
fieldset, div {
margin-left:10px;
margin-top:20px;
margin-bottom:20px;
}
fieldset {
border: 1px solid gray;
padding:10px;
padding-right:20px;
width:50%;
}
#progress {
padding:1px;
padding-left:5px;
padding-right:5px;
margin:0px;
border: 1px solid #333333;
color:#FFFFFF;
background-color:#808080;
text-align:center;
}
</style>
</head>
<body>
<fieldset>
<legend>Formulaire d'upload</legend>
<form enctype="multipart/form-data" method="post" action="" target="uploadFrame" onsubmit="verifUpload();">
<p>
<input type="hidden" id="keyFile" name="APC_UPLOAD_PROGRESS" value="<?php echo uniqid();?>" />
<input type="file" name="fileToUpload" /><br /><br />
<input type="submit" value="Uploader (10Mo max)" />
</p>
</form>
</fieldset>
<fieldset>
<legend>Informations</legend>
<p>
<strong>Nom du fichier</strong> : <span id="fileName"><em>Aucun fichier chargé</em></span><br /><br />
<strong>Progression</strong> :<br /><br /><span id="progress"><em>Aucun fichier chargé</em></span>
</p>
</fieldset>
<iframe id="uploadFrame" name="uploadFrame" style="display:none"></iframe>
</body>
</html>
Le javascript apc.js :
function getXHR() {
var xhr = null;
if(window.XMLHttpRequest || window.ActiveXObject) {
if(window.ActiveXObject) {
try {
xhr = new ActiveXObject('Msxml2.XMLHTTP');
} catch(e) {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
} else {
xhr = new XMLHttpRequest();
}
} else {
return null;
}
return xhr;
}
function verifUpload() {
xhr = getXHR();
if(xhr && xhr.readyState != 0) {
xhr.abort();
}
var keyFile = document.getElementById('keyFile').value;
xhr.open('POST', 'verifUpload.php', true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send('keyFile='+ keyFile);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
if(xhr.responseText != 'false') {
var response = eval('('+xhr.responseText+')');
document.getElementById('fileName').innerHTML = response.filename;
document.getElementById('progress').innerHTML =
Math.round(response.current / response.total * 100) + '%';
document.getElementById('progress').style.display = 'block';
document.getElementById('progress').style.width =
(response.current / response.total * 100) + '%';
if(response.done != 1) {
verifUpload();
}
} else {
verifUpload();
}
}
};
}
Et le fichier php "verifUpload.php" qui récupère l'état d'avancement :
<?php
header('Content-type:text/plain;charset=utf-8');
if(isset($_POST['keyFile'])) {
$fileInformation = apc_fetch('upload_'.$_POST['keyFile']);
echo json_encode($fileInformation);
}
exit;
?>
Le tout sur ton serveur, au même niveau de l'arborescence, ça donne quoi ? (ça devrait être ça)
C'est étrange, j'ai déjà eu ce problème là moi aussi mais je ne sais plus comment je m'en suis sorti... sans doute un truc tout bête qui m'avait échappé.
Essaye de modifier le php comme ça :
Dans ton javascript, tu insert une alerte pour avoir la réponse avec un compteur pour ne pas planter le navigateur :
Tu auras peut-être autre chose que "false" qui sortira.
Autre chose toute bête, si tu utilise dreamweaver, est-ce que la case "inclure une signature unicode" est cochée par défaut quand tu veux enregistrer un nouveau document ?
Tu peux nous mettre un lien vers ton phpinfo ?
Essaye de modifier le php comme ça :
<?php
header('Content-type:text/plain;charset=utf-8');
if(isset($_POST['keyFile'])) {
$fileInformation = apc_fetch('upload_'.$_POST['keyFile']);
// Si ça renvois false :
if ($fileInformation == 'false') {
$fileInformation = "la clé passée est : ".$_POST['keyFile'];
}
echo json_encode($fileInformation);
}
// On ne sait jamais que ta clé ne soit pas passée :
else {
$fileInformation = "pas de keyFile";
echo json_encode($fileInformation);
}
exit;
?>
Dans ton javascript, tu insert une alerte pour avoir la réponse avec un compteur pour ne pas planter le navigateur :
var i = 0;
function verifUpload() {
xhr = getXHR();
if(xhr && xhr.readyState != 0) {
xhr.abort();
}
var keyFile = document.getElementById('keyFile').value;
xhr.open('POST', 'verifUpload.php', true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded" );
xhr.send('keyFile='+ keyFile);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
if (i < 10) {
alert (xhr.responseText);
i++;
}
if(xhr.responseText != 'false') { blablablabla....
Tu auras peut-être autre chose que "false" qui sortira.
Autre chose toute bête, si tu utilise dreamweaver, est-ce que la case "inclure une signature unicode" est cochée par défaut quand tu veux enregistrer un nouveau document ?
Tu peux nous mettre un lien vers ton phpinfo ?
Lassé par la pub ? Créez un compte
- Contenus similaires :
Tags :
- ForumPhp javascript barre de progression
- ForumBarre de progression formulaire d'upload
- solutionsBarre de progression php
- ForumBarre de progression en php
- ForumBarre progression php
- ForumFaire une barre de progression php
- ForumBarre de progression timer javascript
- ForumBarre de progression c
- ForumBarre progression excel 2007
- ForumUpload barre de progression
- Voir plus