IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Upload d'un gros fichier


Sujet :

Langage PHP

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    187
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 187
    Points : 110
    Points
    110
    Par défaut Upload d'un gros fichier
    Bonjour,

    J'ai une solution mutualisée OVH, et sur mon site j'essaie de faire de l'upload de photo en angularjs/php. Sur un fichier moyen (5Mo, upload en 1 minute), tout fonctionne
    - L'image se retrouve à son emplacement définitif
    - L'image est redimensionnée
    - L'enregistrement est ensuite correctement créé en base de donnée pour cette image

    Par contre sur un fichier un peu plus lourd (15Mo, 4 minutes), je ne comprend pas trop ce qui se passe...
    Concrètement, j'utilise angular js, grâce auquel je contrôle l'avancement de mon upload :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    $scope.uploadEnCours = {etat:true,nombrePhoto:$files.length,nombrePhotoReussi:0,nombrePhotoEchec:0,pourcentPhoto:0};
    	    for (var i = 0; i < $files.length; i++) {
    	      var file = $files[i];
    	      $scope.upload = $upload.upload({
    	        url: '/restservice/AlbumPhotoRestService.php?idAlbumPhoto='+$scope.albumPhoto.id+"&cmd=uploadPhoto&typePhoto=PHOTO",
    	        file: file,
    	        headers: { "Content-Type": file.type },
    	      }).progress(function(evt) {
    	    	  $scope.uploadEnCours.pourcentPhoto=parseInt(100.0 * evt.loaded / evt.total);
    	      }).success(function(data, status, headers, config) {
    	        $scope.uploadEnCours.nombrePhotoReussi = $scope.uploadEnCours.nombrePhotoReussi + 1; 
    	        if ($scope.isTransfertTermine()) {
    	        	$scope.getListePhoto();
    	        }
    	      }).error(function(data, status, headers, config) {
    	        console.log(data);
    	        $scope.uploadEnCours.nombrePhotoEchec = $scope.uploadEnCours.nombrePhotoEchec + 1;
    	        if ($scope.isTransfertTermine()) {
    	        	$scope.getListePhoto();
    	        }
    	      });
    	    }
    En php, je récupère mon fichier comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    protected function uploadPhoto() {
    		$tempFile = $_FILES['file']['tmp_name'];
    		$tempPath = dirname($tempFile);
    		$tempName = basename($tempFile);
    		$idAlbumPhoto = ParameterGetter::getRequestParameter("idAlbumPhoto",true);
    		$typePhoto = ParameterGetter::getRequestParameter("typePhoto",true);
    		$targetPath = AlbumPhotoService::getFolderAlbumPhoto($idAlbumPhoto);
    		$fileName = $_FILES['file']['name'];
    		$fileName = preg_replace('/([^.a-z0-9]+)/i', '_', $fileName);
     
     
                    Logger::getLogger()->logInfo("Upload d'une photo dans le répertoire $targetPath ($fileName)");
    		@mkdir(str_replace('//','/',$targetPath), 0755, true);
     
     
    		$targetFile =  str_replace('//','/',$targetPath) . $fileName;
    		move_uploaded_file($tempFile,$targetFile);
    		str_replace($_SERVER['DOCUMENT_ROOT'],'',$targetFile);
    		fctredimimage(1280, 1280, '', '', $targetPath, $fileName, 90);
    		PhotoService::createEnregistrementPhoto($idAlbumPhoto, $fileName,'', $typePhoto);
    	}
    Ce que je vois, dans le cas d'un fichier trop gros :
    - L'upload arrive bien à 100%
    - Mon script php est lancé, mais fileName est vide (visible dans le log : "Upload d'une photo dans le répertoire /monSite/www/data/albumphoto/29/ ()")
    - Une enregistrement avec un nom de fichier vide est créé en base de données
    - Mon image n'existe pas dans le répertoire de destination

    J'ai essayé avec un phpinfo de voir ce qui pourrait être en cause, mais je ne trouve rien qui soit en dehors des clous :
    - max_execution_time = 300
    - max_input_time = -1
    - post_max_size = 64M
    - upload_max_filesize = 64M

    Quelqu'un saurait d'où vient le problème?

    Merci!

  2. #2
    Membre actif
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2007
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2007
    Messages : 314
    Points : 217
    Points
    217
    Par défaut
    bonjour ,

    ce que je te recommande est d'ajouter à ton code une petite gestion des erreurs avec : $_FILES['file']['error'] .

    comme ça tu peux au moins savoir ce qui se passe

  3. #3
    Membre éprouvé Avatar de Shuty
    Homme Profil pro
    Ingénieur en développement
    Inscrit en
    Octobre 2012
    Messages
    630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur en développement
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2012
    Messages : 630
    Points : 1 174
    Points
    1 174
    Par défaut
    As tu regardé les log php ?
    Agence web Dim'Solution, créateur de solutions numériques
    Sites internet, ecommerce, logiciels, applications mobiles, référencement (SEO), plugin Prestashop, Magento, WordPress, Joomla!...

    Cours de trading gratuit | Envoyer des sms gratuitement | Envoyer des fax gratuitement | Plateforme de Fax à l'international

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    187
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 187
    Points : 110
    Points
    110
    Par défaut
    Bonjour, et merci pour vos réponses !

    En fait mon $_FILES['file'] est vide dans le cas qui pose problème, j'ai fait évoluer le début de mon service :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    $tempFile = $_FILES['file']['tmp_name'];
    $errorUpload = $_FILES['file']['error'];
    $tempPath = dirname($tempFile);
    $tempName = basename($tempFile);
    $idAlbumPhoto = ParameterGetter::getRequestParameter("idAlbumPhoto",true);
    $typePhoto = ParameterGetter::getRequestParameter("typePhoto",true);
    $targetPath = AlbumPhotoService::getFolderAlbumPhoto($idAlbumPhoto);
    $fileName = $_FILES['file']['name'];
    $fileName = preg_replace('/([^.a-z0-9]+)/i', '_', $fileName);
    if ($errorUpload != null && $errorUpload != '') {
    	Logger::getLogger()->logError("Erreur d'upload : $errorUpload");
    }
    if ($_FILES['file'] != null) {
    	foreach ($_FILES['file'] as $libelle=>$contenu) {
    		Logger::getLogger()->logError("CONTENU $libelle : $contenu");
    	}
    } else {
    	Logger::getLogger()->logError("Le tableau est null!");
    }
    Le seul log qui s'affiche est : Le tableau est null!

    Pour ce qui est des logs php, je redirige tout (je pense) dans un fichier grâces aux directives :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    error_reporting(E_ALL);
    ini_set('display_errors', 'Off');
    ini_set('log_errors', 'On');
    ini_set('error_log', $_SERVER["DOCUMENT_ROOT"] . '/logs/log_'.date("y-m-d").'-systemError.log');
    Dans le fichier en question, je trouve :
    [29-Apr-2014 19:56:40 Europe/Paris] PHP Notice: Undefined index: file in monSite/www/restservice/AlbumPhotoRestService.php on line 98
    [29-Apr-2014 19:56:40 Europe/Paris] PHP Notice: Undefined index: file in monSite/www/restservice/AlbumPhotoRestService.php on line 99
    [29-Apr-2014 19:56:40 Europe/Paris] PHP Notice: Undefined index: file in monSite/www/restservice/AlbumPhotoRestService.php on line 105
    [29-Apr-2014 19:56:40 Europe/Paris] PHP Notice: Undefined index: file in monSite/www/restservice/AlbumPhotoRestService.php on line 112
    [29-Apr-2014 19:56:40 Europe/Paris] PHP Warning: strpos(): Empty needle in monSite/www/outils/photo/redimmensionneur.php on line 55
    Le dernier warning étant lié au fait que je passe un nom de fichier vide à ma méthode...

    J'ai refait le test avec une petite image, c'est toujours OK !

    Un idée??

    Merci d'avance !

  5. #5
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Eventuellement tu pourrais tester l'upload avec cette classe d'upload. Elle est fournie avec un répertoire de test pré configuré et des fichiers exemples. Il te faudra donc moins de cinq minutes pour faire des essais. L'avantage est qu'elle gère les erreurs et même si tu ne t'en sert pas à terme, elle te permettra sans doute de faire afficher le message d'erreur correspondant et de mieux cerner ton problème.

  6. #6
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2007
    Messages
    748
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 748
    Points : 1 022
    Points
    1 022
    Par défaut
    perso, je vois bien un problème de limite dans httpdconf que tu dois pouvoir gérer avec php.ini ou .htaccess en mutualisé

    php.ini max_upload_filesize
    Conception / Dev

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    187
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 187
    Points : 110
    Points
    110
    Par défaut
    Bonjour, et merci pour vos réponses !

    Effectivement, j'ai testé avec cette classe d'upload, et le message remonté est :
    - Le poids total maximum du formulaire autorisé par le serveur est dépassé (64M)
    64M, c'est la valeur de mon max_upload_filesize, donc, c'est cohérent !

    Par contre, là où je ne comprend pas, c'est que mon fichier fait 15,6Mo (16 454 164 octets précisément d'après Windows) !

    J'ai essayé d'ordonner mes photos de la plus grosses à la moins grosse et de les uploader une par une pour détecter celle où ça commence à passer
    - 14*352*390 octets, ça passe pas
    - 14*219*673 octets, ça passe

    Donc j'ai bien une limite de taille, mais pas du tout là où elle devrait être ! Quelqu'un aurait une idée du pourquoi du comment??

    Merci !

  8. #8
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2007
    Messages
    748
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 748
    Points : 1 022
    Points
    1 022
    Par défaut
    tu devrais peu être libérer les ressources avec un ob-flush, avant chaque envoi d'un nouvelle image, si des fois la class upload ne le fait pas... http://www.php.net/manual/fr/function.ob-flush.php
    Conception / Dev

  9. #9
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Citation Envoyé par legentil Voir le message

    J'ai essayé d'ordonner mes photos de la plus grosses à la moins grosse et de les uploader une par une pour détecter celle où ça commence à passer
    - 14*352*390 octets, ça passe pas
    - 14*219*673 octets, ça passe
    Cela correspond à quoi les 14*352*390 et 14*219*673, d'où tu sort ces chiffres ? Quand on fait le total des multiplications (dont je me demande à quoi correspondent les nombres) le second résultat est supérieur au premier. Cela voudrait dire qu'un fichier plus gros passe plus facilement qu'un plus petit ?

    Je viens de faire le test avec la classe (et l'exemple Basique.php) et j'ai pu téléchargé sans problème un fichier .png de 17 Mo puis ensuite un autre fichier de 28 Mo sur un mutualisé (offre perso chez ovh) en 10 minutes environ avec ma connexion de 1 MB ascendante.

    Je ne vois pas d'où peut venir ton pb. La seule erreur que ne peut pas intercepter la classe c'est la directive timeout d'apache (rien à voir avec max_execution_time) mais dans ce cas le serveur renvoie normalement une erreur serveur de dépassement de temps (et cette erreur est plutôt rare car habituellement ce paramètre est réglé pour être cohérent avec le reste de la configuration). Si tu as bien testé la classe indépendamment d'un autre script, apparemment ton post dépasse bien les 64 Mo (et donc en cas de dépassement post_max_size les globales $_POST et $_FILES sont effectivement vides).

    Tu es chez quel hébergeur ? Peux-tu mettre à disposition ton fichier quelque part sur le web pour que j'essaie de faire le test avec ?

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    187
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 187
    Points : 110
    Points
    110
    Par défaut
    Salut, et merci pour vos réponses !

    Déjà, pour les chiffres, je les ai copié collé de la fenêtre de propriété d'éclipse, initialement à la place des *, ce sont des
    espaces, je ne comprend pas comment des * sont venu se mettre ici . Bref, c'est la taille des fichiers en octets (donc là grosso
    modo, ce sont 2 fichiers de 14Mo, le second étant juste un poil plus grand que le premier).

    Par rapport au ob_flush, j'ai du mal à voir un rapport, vu que ça travaille sur un buffer de sortie (qui ne pèse que quelques kilos). Même dans le cas où il ne serait pas libéré, je ne pense donc pas que ça viendrait impacter un upload de fichier !

    Oui j'ai testé la classe d'upload directement avec les exemples fournis (le message d'erreur ne s'affichait pas avec le basique,
    j'ai donc fini mes tests avec le "Upload_multiple_multiple.php")

    J'ai téléchargé wireshark pour vérifier la taille de mon envoi, et visiblement, quand je clique sur la requête d'envoi, il me
    donne une taille (reconstruite à partir des 13000 paquets) de 18762655 octets, donc de ce côté là, je suis bon, mon POST ne fait
    que 18 Mo.

    Je suis chez OVH avec une offre mutualisée "Pro" (celle à 5€/mois).

    J'ai également un serveur en offre perso, j'ai fait le même test dessus, et là mon upload fonctionne .
    Le fichier lui même que j'uploade n'est donc pas à mettre en cause (surtout que j'ai le même comportement avec plusieurs images,
    j'ai reproduit sans problème avec un pdf de 20 Mo aussi)

    J'ai donc comparé les infos php des deux serveurs (Je ne suis pas sûr que ce test soit pertinent, étant donné que la version des
    deux serveurs n'est pas la même, mais je commence à manquer de pistes ), voilà ce que je relève comme différences (je n'ai pas noté toutes les différences, juste celles qui me semblaient utiles) :

    Version :
    pro : 5.4.27
    perso : 5.3.16

    max_execution_time :
    pro : 300
    perso : 120

    max_input_time :
    pro : -1
    perso : 60

    max_input_vars :
    pro : 16000
    perso : 2000

    memory_limit :
    pro : 512M
    perso : 128M

    error_reporting :
    pro : 32759
    perso : 30711

    serialize_precision :
    pro : 17
    perso : 100

    session.gc_divisor :
    pro : 100
    perso : 1000

    session.use_only_cookies :
    pro : on
    perso : off

    J'ai également de valeurs présentes uniquement sur le pro :
    zend.detect_unicode On On
    zend.multibyte Off Off
    zend.script_encoding no value no value

    enable_post_data_reading On On

    session.upload_progress.cleanup On On
    session.upload_progress.enabled On On
    session.upload_progress.freq 1% 1%
    session.upload_progress.min_freq 1 1
    session.upload_progress.name PHP_SESSION_UPLOAD_PROGRESS PHP_SESSION_UPLOAD_PROGRESS
    session.upload_progress.prefix upload_progress_ upload_progress_

    Opcode Caching Up and Running
    Optimization Enabled
    Startup OK
    Shared memory model mmap
    Cache hits 2119697
    Cache misses 111172
    Used memory 1073461864
    Free memory 16
    Wasted memory 279944
    Interned Strings Used memory 4194280
    Interned Strings Free memory 24
    Cached scripts 20043
    Cached keys 21568
    Max keys 32531
    OOM restarts 0
    Hash keys restarts 0
    Manual restarts 0
    opcache.blacklist_filename no value no value
    opcache.consistency_checks 0 0
    opcache.dups_fix Off Off
    opcache.enable On On
    opcache.enable_cli Off Off
    opcache.enable_file_override Off Off
    opcache.error_log no value no value
    opcache.fast_shutdown 0 0
    opcache.file_update_protection 2 2
    opcache.force_restart_timeout 180 180
    opcache.inherited_hack On On
    opcache.interned_strings_buffer 4 4
    opcache.load_comments 1 1
    opcache.log_verbosity_level 1 1
    opcache.max_accelerated_files 32000 32000
    opcache.max_file_size 0 0
    opcache.max_wasted_percentage 5 5
    opcache.memory_consumption 1024 1024
    opcache.optimization_level 0x7fffffef 0x7fffffef
    opcache.preferred_memory_model no value no value
    opcache.protect_memory 0 0
    opcache.restrict_api /home/ovh/fpm5.4/opcache-status.php /home/ovh/fpm5.4/opcache-status.php
    opcache.revalidate_freq 2 2
    opcache.revalidate_path Off Off
    opcache.save_comments 1 1
    opcache.use_cwd On On
    opcache.validate_timestamps On On

    Et des valeurs présentes uniquement sur le perso
    allow_call_time_pass_reference On On
    register_globals Off Off
    register_long_arrays On On
    safe_mode Off Off
    safe_mode_exec_dir /home/ /home/
    safe_mode_gid Off Off
    safe_mode_include_dir no value no value

    memcached support enabled
    Version 1.0.2
    libmemcached version 0.40
    Session support yes
    igbinary support no

    J'avoue que la plupart de ces options ne me parlent pas du tout, mais pour celles qui me parlent, je ne vois rien de choquant !

    Des idées?

  11. #11
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Oui c'est bizarre que ça passe sur une offre perso et pas sur une offre pro. Apparemment c'est un problème spécifique à ton hébergement.

    Tu as essayé de demander l'explication au sav d'ovh ? Ou dans un premier temps essaies le forum ovh, les membres sont assez réactif et on a souvent des réponses.

  12. #12
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Bonjour,

    Je viens de retrouver ce sujet en bonne place sur google pour l'upload de gros fichiers en php.

    Juste pour dire que depuis ces précédents messages j'ai fait une seconde classe d'upload qui permet de télécharger des gros fichiers quelque soit la configuration serveur (surpasse les configurations serveur).

    C'est une classe ajax/html5 - avec des exemples php côté serveur - qui propose l'affichage des informations en temps réel et la possibilité de reprendre un upload éventuellement interrompu en utilisant la partie du fichier déjà uploadée.

    Elle est fournie dans un dossier de test pré configuré avec de nombreux exemples dont un prêt à l'emploi, finalisé et customisé qui propose les fonctionnalités suivantes :
    - upload multiple,
    - drag and drop supporté,
    - prévisualisation des photos (si les fichiers sont des photos),
    - informations en temps réel,
    - pas de limite de taille (sauf si besoin celle souhaitée par vous-même),
    - boutons d'arrêt pour chaque fichier,
    - css responsive design.

    Classe UploadAjaxABCI

    (fonctionne tout aussi bien pour des petits fichiers )


    Note : La classe ajax/html5 peut fonctionner également avec une autre technologie côté serveur, il suffit de prendre exemple sur la classe php fournie.

Discussions similaires

  1. [VB.net 2005] Upload FTP de gros fichiers
    Par Bz dans le forum Windows Forms
    Réponses: 4
    Dernier message: 01/12/2008, 11h58
  2. [Upload] Upload d'un gros fichier + barre de progression
    Par Night_owl dans le forum Langage
    Réponses: 4
    Dernier message: 27/03/2008, 15h14
  3. [Upload] Envoi de gros fichiers
    Par zevince dans le forum Langage
    Réponses: 1
    Dernier message: 12/10/2007, 17h11
  4. [Upload] Génération de gros fichiers
    Par silef dans le forum Langage
    Réponses: 8
    Dernier message: 12/04/2007, 12h04
  5. Réponses: 5
    Dernier message: 12/09/2006, 00h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo