Aller au contenu

8 mai 2010

70

Barre de progression pour upload en PHP/AJAX/APC

Dans ce nouvel article, nous allons voir comment utiliser le cache APC (voir ici pour son installation), afin de réaliser une barre de progression lors de l’upload de vos fichiers. L’utilisation de cette méthode apporte de nombreux avantages:

  • elle met en attente l’utilisateur sans pour autant geler le navigateur ;
  • l’utilisateur peut voir la progression de l’upload ;
  • il n’y a plus de limite en terme de poids.

Toutefois, il faut des connaissances solides en PHP et JavaScript, comprendre le fonction asynchrone en AJAX, et je ne parle même pas du fonctionnement du cache APC.

Je ne vais pas détailler tout le code à mettre en place ou mon article serait trop long et fastidieux à lire. En revanche j’ai pris la peine de réaliser un petit schéma explicatif. Les images sont libres de droits et téléchargées ici.

Si vous avez bien compris, tout se passe de manière asynchrone en AJAX. Pour faire simple, le navigateur n’a pas été rechargé, mais au moins une requête a été envoyée au serveur (1). Cette requête à pour but de lancer un script PHP, qui va consulter le cache APC (2) et nous retourner diverses informations (nom du fichier, son poids total etc…). Une fois toutes ces informations récupérées, le navigateur (le code JavaScript en réalité) va lire la réponse du serveur, qui se trouve être du JSON très facile à utiliser pour nos besoins. Il nous reste plus qu’à mettre à jour (3) notre barre de progression.

Voici le résultat pour le même fichier à transférer:

Composition des sources:

  • ./js/prototpye/*
  • ./js/scriptaculouts/*
  • ./js/img/*./js/cupload.js
  • ./js/cprogressbar.js
  • ./js/cprogressbar.css
  • ./upload/
  • ./index.html
  • ./upload.php

Le code JavaScript qui gère l’upload (AJAX + Barre de progression) se trouve dans le fichier cupload.js. Le script appelé pour la consultation du cache APC et qui retourne du JSON est dans upload.php.

Ces sources datent de l’année dernière, je les ai adapté pour réaliser ce petit tuto. Il y a des améliorations à apporter notamment au niveau de la validation des fichiers (jpg, jpeg, png etc…). En effet il serait dangereux voire suicidaire d’autoriser l’upload de fichiers PHP par exemple. N’oubliez pas de donner les droits suffisants au répertoire upload qui va contenir tous vos fichiers transférés. Dans un prochain tuto, nous verrons la démarche à suivre pour réaliser le même type d’upload (avec barre de progression) mais avec Flex cette fois-ci!

Télécharger les sources

70 commentaires Rédiger un commentaire
  1. sept 24 2010

    De rien rodliw, mais rien ne t’empêche de travailler avec la version 5 de PHP que tu utilises ou pas la notion d’objet. C’est même plutôt conseillé !

  2. Mat
    oct 19 2010

    Bonjour Adrien,

    Tout d’abord merci pour ce tuto !!!

    Je souhaiterais modifier la source pour pouvoir envoyer un maximum de 10 fichiers les uns à la suite des autres en une fois.

    Peux-t-on envisager cette modification ? Si oui que dois-je modifier dans cupload.js ?

    J’ai déjà trouvé où se construit le formulaire (ajout d’input), mais le traitement de plusieurs input reste nébuleux.

    Merci d’avance pour les éventuelles pistes ou réponses.

  3. oct 19 2010

    Salut Mat, c’est tout à fait possible d’envoyer plusieurs fichiers, il suffit pour cela d’instancier autant de fois que nécessaire un objet d’upload :

    var cupload = new CUpload ();
    cupload.create ($(‘cupload’));

    var cupload1 = new CUpload ();
    cupload1.create ($(‘cupload1′));

    var cupload2 = new CUpload ();
    cupload2.create ($(‘cupload2′));

    etc…

    depuis le fichier index.html … j’avais déjà testé et ça fonctionnait parfaitement !

    A + :)

  4. Mat
    oct 19 2010

    Merci pour la rapidité de ta réponse !

    Effectivement après test j’ai bien plusieurs champ parcourir, mais j’aurais voulu traiter tout ces fichiers en une fois.

    On sélectionne ses fichiers puis on valide une fois pour tout les fichiers.

    Ayant encore du mal à tous comprendre :

    - ne peut-on pas modifier la construction du formulaire pour qu’il puisse traiter de 1 a x champs en les stockant dans un tableau par exemple.

    merci d’avance.

  5. oct 19 2010

    A mon avis ça doit être possible mais pour le coup c’est une grosse partie du code à modifier. Si j’ai bien compris, il faudrait un bouton pour x champs d’upload, puis lors du clic sur ce dernier lancer tous les uploads en même temps ? D’un point de vu technique c’est très certainement possible, il faudrait avec jquery faire remonter un événement de type ‘submit’ sur tous les formulaires. Je sais que c’est possible mais je ne me souviens plus de qu’elle façon. Puisque le traitement est asynchrone ça ne posera pas de problème. En revanche, je ne connais pas la config de ton serveur, mais si dix personnes réalisent dix uploads en même temps … ça risque de saturer légèrement !

  6. Alex
    déc 7 2010

    Bonjour,

    Et d’abord merci énormément pour ce code!!

    Il me reste un soucis à élucider : pour des fichiers jusque 300Ko aucun problème, si je suis au dela, j’ai le message « Impossible de transférer ce fichier. » et je n’arrive pas à comprendre le pourquoi du comment!!!

  7. déc 7 2010

    Bonjour Alex,
    A première vu le problème doit venir de la configuration du serveur … il faut regarder du coté du php.ini, attention il y a deux lignes importantes à prendre en considération :

    upload_max_filesize = 100M
    post_max_size = 100M

    bonne chance !

  8. nov 17 2011

    Salut Adrien,

    article vraiment intéressant. Il date désormais un peu mais il est tout à fait possible de l’adapter, par exemple à la libraire JS jQuery.

    L’upload de fichiers en AJAX est souvent nécessaire (plutôt que l’utilisation d’un composant flash). Ce bout de code peut s’avérer bien utile dans bon nombres de situations.

    Merci pour le partage. ;)

  9. nov 17 2011

    Merci Nicolas pour ton commentaire,
    tout dépend des besoins en fait, mais j’avoue quand même avoir une préférence pour l’utilisation de l’AJAX.

    A bientôt :)

  10. Luc DENNERY
    déc 10 2011

    Bonjour,
    J’ai souhaité essayé d’utiliser votre script et j’ai rencontré un drôle de problème :
    Le transfert des fichiers psd échouent systématiquement alors que pour les autres format, celà passe très bien. Auriez vous une idée d’où cela pourrai venir?
    Merci d’avance.
    Cordialement

    Luc. D

  11. déc 11 2011

    Bonjour,
    Avez-vous regardé du coté du php.ini :

    upload_max_filesize = 100M
    post_max_size = 100M

    s’il s’agit d’un PSD (ils sont plutôt lourd selon les cas), je pense que ça vient d’un problème de poids du fichier.

    Cordialement,
    Adrien.

  12. Luc DENNERY
    déc 11 2011

    Je vous remercie de votre réponse rapide, et c’est effectivement le premier paramètre que j’ai regardé. Néanmoins, j’ai pu transférer avec succès un mp4 de 450M (test avec upload_max_filesize = 600M & post_max_size = 600M) et le fichier est passé comme une lettre à la poste. Par contre avec différent PSD échelonnés de 150K à 8M ça ne passe toujours pas. J’ai fait le test avec une 50aine de fichiers aux formats et tailles différentes et je n’ai jamais de problème, excepté avec les PSD… Curieux n’est ce pas.
    Je vais continuer à creuser et jeter un coup d’oeil sur les logs serveur au cas où.
    Merci encore
    Cordialement

    Luc D.

  13. déc 11 2011

    En effet c’est relativement curieux … il faudrait effectivement regarder du coté des log d’apache et pourquoi pas ceux d’APC aussi… est-ce qu’on serait sur le point de tomber sur un nouveau mystère !? Bon courage pour vos recherches, laissez-moi un message si jamais vous trouvez une solution à ce problème, je vais essayer de chercher aussi de mon coté, car ça me parait vraiment étrange!

    Cordialement,
    Adrien

  14. Luc DENNERY
    déc 11 2011

    Bonsoir,
    si cela vous convient, je vous propose de continuer cette conversation par mail.
    Luc D.

  15. Luc DENNERY
    déc 13 2011

    Bonsoir, le problème est résolu. C’est les fonctionnalités de protection d’un routeur CISCO qui en est la cause. Un ticket a été ouvert chez eux. Les caractéristique d’un fichier PSD en transit vers apache correspondrai à une signature de Syn Flood. Désolé pour le dérangement et merci encore

    Luc D.

  16. déc 13 2011

    Pas de problème, content d’avoir pu aider ;) , et merci pour le retour.

  17. Younes
    fév 28 2012

    Bonsoir

    voila , j’ai 2 sites dans le meme serveur didié , et je vais que le site2.com puisse telecharger des dossiers a partir de mon site1.com

    Exemple: dans le Site2.com , j’appuye sur le bouton  » telecharger » une fenetre (popup ou Iframe ) vas s’ouvrir cette fenetre qui contient le Site1.com puis il choisit un dossier ou appuyant sur un bouton , et ce dossier la vas ce mettre directement dans un repertoire dans le Site2.com

    merci de votre repense

  18. mar 1 2012

    Bonsoir,
    si c’est sur le même serveur, pourquoi passer par du socket ? Un simple copy avec le path des fichiers sur le disque ne serait-il pas plus efficace ?

Rétro-liens & Pings

  1. Migration sous wordpress | Adrien RUIZ » devblog
  2. Télécharger un fichier d’un serveur vers un autre | Adrien RUIZ » devblog

Donnez votre avis, envoyez un commentaire

(required)
(required)

Note: le code HTML est autorisé. Votre adresse mel ne sera jamais publiée.

S'abonner aux commentaires