8792 sujets

Développement web côté serveur, CMS

bonjour,

lorsque j'essaie d'uploader une image (JPG, 2.9MB, 3456x2304 px) avec le script suivant, j'obtient cette erreur :

a écrit :
Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 13824 bytes) in /home/www/b7592a9d050f4b86f67ae26685348f5a/web/test/html/upload.php on line 111



<?php

ini_set("memory_limit","20M");

?>

<?php
//----------------------------
// DEFINITION DES VARIABLES
//----------------------------
 
//Pour les tester en local (avec EasyPHP,...)
$test_local = 0; //0 pour le web                                                    //N'effectue pas la réalocation de la mémoire du serveur
                                                                                                                    //et n'envoi pas de mail de confirmation
 
$extension = 'image/pjpeg'; // MIME JPEG pour la comparaisond de l'extention du fichier
$extension2 = 'image/jpeg'; // MIME JPEG pour la comparaisond de l'extention du fichier
                            //$extension3 = 'image/png'; // AFIN DE REJOUTER DES EXTENSIONS // VOIR EGALEMENT LIGNE 102 // ATTENTION, LE GD MARCHE SEULEMENT AVEC JPG
                            //$extension4 = 'image/gif';
$quality = 100; // Qualité de la compression JPEG
$kb_max = 70000; // Valeur max en octets de l'image finale
$max_size = 50000000; // Taille max en octets du fichier à uploader pour traitement
$largeurDestination = 466; // Largeur max de l'image finale en pixel
$nom_rep = "upload"; // Lien du répertoire des dossier photos à la raçine du script (fin sans /)
$site = "http://".$_SERVER["HTTP_HOST"]."/test/html/"; // Adresse du dossier où est installé le script (fin avec /)

 
//---------------------------------------------
// DEFINITION DES VARIABLES LIEES AUX FICHIERS
//---------------------------------------------
 
$nom_file = $_FILES['fichier']['name'];
$taille = $_FILES['fichier']['size'];
$tmp = $_FILES['fichier']['tmp_name'];
$ext_img            =    $_FILES['fichier']['type'];
$verif_exist = $nom_rep;
$verif_exist .= "/";
$verif_exist .= $nom_file;
       
//----------------------
// SCRIPT D'UPLOAD
//----------------------
 

                
//Enlever les accents
//*******************
function enlever_accents($dest_fichier){
$dest_fichier = strtr($dest_fichier, 'ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ/',
                                     'AAAAAACEEEEIIIIOOOOOUUUUYaaaaaaceeeeiiiioooooouuuuyy/');
//remplacer les caracteres autres que lettres, chiffres et point par _
$dest_fichier = preg_replace('/([^.a-z\/0-9]+)/i', '_', $dest_fichier);
return $dest_fichier;
}
 
$nom_rep = enlever_accents($nom_rep);
$verif_exist = enlever_accents($verif_exist);
$nom_file = enlever_accents($nom_file);
 
//Début de la procédure d'upload
//******************************
if($_POST['posted']) {
      //On vérifie que le nom du fichier n'existe pas
      if(!file_exists($verif_exist)) { 
        // On vérifie l'extension du fichier 
        if(($ext_img == $extension)||($ext_img == $extension2)) {   // ||($ext_img == $extension3)||($ext_img == $extension4) // A RAJOUTER POUR AJOUTER DES EXTENSION
           // On récupère les dimensions du fichier
           $infos_img = getimagesize($tmp);
            // On vérifie la taille de l'image
             if($taille <= $max_size) { 
               //upload du fichier
               if(move_uploaded_file($tmp,$nom_rep."/".$nom_file)) {
                    // Si upload OK alors on affiche le message de réussite
                    chmod($verif_exist, 0777);
                    echo '<font color=#C19163 face="Arial, Helvetica, sans-serif" font size="2"><b>IMAGE UPLOADEE AVEC SUCCES !</b><br></font>';
                    echo '<hr />';
                    echo '<font color=#C19163 face="Arial, Helvetica, sans-serif" font size="1"><u>DETAILS DE L\'IMAGE D\'ORIGINE :</u><br></font>';
                    echo '<br />';
                    echo '<font color=#C19163 face="Arial, Helvetica, sans-serif" font size="1"><b>FICHIERS :</b> ', $nom_file , '<br /></font>';
                    echo '<font color=#C19163 face="Arial, Helvetica, sans-serif" font size="1"><b>TAILLE :</b> ' , $taille, ' Octets<br /></font>';
                    echo '<font color=#C19163 face="Arial, Helvetica, sans-serif" font size="1"><b>LARGEUR :</b> ', $infos_img[0], ' px<br /></font>';
                    echo '<font color=#C19163 face="Arial, Helvetica, sans-serif" font size="1"><b>HAUTEUR :</b> ', $infos_img[1], ' px<br /></font>';
                    echo '<hr />';
                     
                    //calcul et redimension
                    //*********************
                    $fichierSource = $nom_rep;
                    $fichierSource .= "/";
                    $fichierSource .= $nom_file;
                    $fichierSource = $fichierSource;
                    //hauteur / largeur
                    $rapport = $infos_img[1] / $infos_img[0];
                    //Dimension de sortie
                    $hauteurDestination = $largeurDestination * $rapport;
                     
                    if($test_local == 0)
                        {
                        //Réaloue la mémoire dont le serveur à besoin
                        //*******************************************
                        $memoryNeeded = round(($infos_img[0] * $infos_img[1] * $infos_img['bits'] * $infos_img['channels'] / 8 + Pow(2, 16)) * 1.65);
                        $mem_in_use= memory_get_usage();
                        //echo "Mémoire utilisée : $memoryNeeded contre $mem_in_use<br><br>";
                        $test = (integer) ini_get('memory_limit') + ceil(((memory_get_usage() + $memoryNeeded) - (integer) ini_get('memory_limit') * pow(1024, 2)) / pow(1024, 2)) + 1;
                        //solution calculée
                        if(function_exists('memory_get_usage') && memory_get_usage() + $memoryNeeded > (integer) ini_get('memory_limit') * pow(1024, 2))
                        ini_set('memory_limit', (integer) ini_get('memory_limit') + ceil(((memory_get_usage() + $memoryNeeded) - (integer) ini_get('memory_limit') * pow(1024, 2)) / pow(1024, 2)) + 2 . 'M');
                        }
                         
                    //Création de l'image
                                            //*******************
                    $source = imagecreatefromjpeg($fichierSource);
                     
                    $largeurSource = imagesx($source);
                    $hauteurSource = imagesy($source);
                                       
                    if($largeurSource > $largeurDestination){
                       $im = ImageCreateTrueColor ($largeurDestination, $hauteurDestination)
                            or die ("Erreur lors de la création de l'image");
                    }
                    else{
                       $im = ImageCreateTrueColor ($infos_img[0], $infos_img[1])
                            or die ("Erreur lors de la création de l'image");
                       $largeurDestination = $infos_img[0];
                       $hauteurDestination = $infos_img[1];
                    }
                       
                    //Redimentionnement
                    //*****************
                    ImageCopyResampled($im, $source, 0, 0, 0, 0, $largeurDestination, $hauteurDestination, $largeurSource, $hauteurSource);
                    
                    //Création du fichier de sortie
                    //*****************************
                    $fh=fopen($fichierSource,'w');
                    fclose($fh);
                    ImageJpeg ($im,$fichierSource,$quality);
                    $size_file = filesize($fichierSource);
                    
                    //Test de la taille en kb de l'image définitive
                    //*********************************************
                    $size_file = filesize($fichierSource);
                    $iteration = 0;
                    while($size_file > $kb_max){
                         if($quality > 0)$quality -= 5;
                         else {$quality = "Erreur!!!"; break;}
                       unlink($fichierSource);
                       $fh=fopen($fichierSource,'w');
                       fclose($fh);
                       ImageJpeg ($im,$fichierSource,$quality);
                       $size_file = filesize($fichierSource);
                       $iteration++;
                    }
 
                    //Affiche le détail de l'image
                    echo '<font color=#C19163 face="Arial, Helvetica, sans-serif" font size="1"><u>DETAILS DE L\'IMAGE FINALE SUR LE SERVEUR :</u><br></font>';
                    echo '<br />';
                    echo '<font color=#C19163 face="Arial, Helvetica, sans-serif" font size="1"><b>FICHIER :</b> ' , $nom_file, '<br /></font>';
                    echo '<font color=#C19163 face="Arial, Helvetica, sans-serif" font size="1"><b>TAILLE :</b> ' , $size_file, ' Octets<br /></font>';
                    echo '<font color=#C19163 face="Arial, Helvetica, sans-serif" font size="1"><b>QUALITE :</b> ' , $quality, ' %<br /></font>';
                    echo '<font color=#C19163 face="Arial, Helvetica, sans-serif" font size="1"><b>LARGEUR :</b> ' , $largeurDestination, ' px<br /></font>';
                    echo '<font color=#C19163 face="Arial, Helvetica, sans-serif" font size="1"><b>HAUTEUR :</b> ' , $hauteurDestination, ' px<br /></font>';
                    echo '<hr />';
                    echo '<font color=#C19163 face="Arial, Helvetica, sans-serif" font size="2"><b>ADRESSE DU FICHIER A COPIER DANS LA NEWS : </b>' , htmlspecialchars('<img src="http://www.gaptrading.ch/html/upload_clients/' . $nom_file . '"></font>');
                    echo '<hr />';
                    echo '<br />';
                    $lien_image = $site.$nom_rep."/".$nom_file;
                    echo '<font color=#C19163 face="Arial, Helvetica, sans-serif" font size="1">L\'IMAGE CI-DESSOUS A ETE REDIMENSIONEE ET UPLOADEE SUR LE SERVEUR AVEC SUCCES !<br><br></font>';
                    //echo "Lien de l'image : ".$lien_image."<br /><br />";
                    echo "<img border='0' src='".$lien_image."'><br />";
                    
                   
                       
                } else {
                    // Sinon on affiche une erreur système
                    echo '<font color=#C19163 face="Arial, Helvetica, sans-serif" font size="2"><b><u>ECHEC DE L\'ENVOI</u><br><br>PROBLEME LORS DE L\'UPLOAD !</b><br /><br /><b>Erreur num : '.$_FILES['fichier']['error']. '</b><br /><br /></font>';
                        }
            } else {
                // Sinon on affiche une erreur pour les dimensions et taille de l'image
                echo '<font color=#C19163 face="Arial, Helvetica, sans-serif" font size="2"><b>LA TAILLE DU FICHIER DEPASSE LA TAILLE MAXIMAL AUTORISEE DE $max_size octets!</b><br /></font>';
                    }
        } else {
            // Sinon on affiche une erreur pour l'extension
            echo '<font color=#C19163 face="Arial, Helvetica, sans-serif" font size="2"><b><u>ECHEC DE L\'ENVOI</u><br><br>VOTRE IMAGE NE COMPORTE PAS L\'EXTENSION .jpg !</b><br /></font>';
                }
      } else {
             //Sinon on demande de renommer
             echo '<font color=#C19163 face="Arial, Helvetica, sans-serif" font size="2"><b><u>ECHEC DE L\'ENVOI</u><br><br>UNE IMAGE AVEC LE MEME NOM EXISTE DEJA ! RENOMMER L\'IMAGE ET RECOMMENCER !</b><br /></font>';
                }

}

?><body bgcolor="#2A1D13" text="#C19163">
      
 <form enctype="multipart/form-data" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">
   <p>&nbsp;</p>
   <p><font size="3" face="Arial, Helvetica, sans-serif"><strong>INSERER UNE IMAGE DANS UNE NEWS  :</strong></font></p>
   <p><font color="#C19163"><strong><font size="1" face="Arial, Helvetica, sans-serif">FICHIERS AUTORISES : .jpg, .jpeg </font></strong></font></p>
   <p><font color="#C19163"><strong><font size="1" face="Arial, Helvetica, sans-serif">TAILLE MAXIMUM AUTORISEE POUR UN FICHIER : 45 MB  </font></strong></font><br />
     <br />
     <br>
     
         <font color="#C19163" face="Arial, Helvetica, sans-serif"><font size="1"><strong>SELECTIONNEZ L'IMAGE :</strong> </font></font>
         <font size="1" face="Arial">
         <input type="hidden" name="posted" value="1">
         </font>
         <input name="fichier" type="file">
     <br>
     <br>
     <input type="submit" value="Envoyer la photo" />
     </p>
     <INPUT Type="Button" Value="Fermer la fen&ecirc;tre" onClick="javascript:parent.close()">
 </form>



Par contre l'image est uploadée sur le server, donc comment faire pour regler ce problème ?


merci d'avance de votre aide
Modifié par alpking (10 Nov 2006 - 10:19)
J'ai lu quelque part qu'il est possible d'augmenter la taille maximale avec des directives dans le fichier .htaccess :

php_value upload_max_filesize 4M
php_value post_max_size 4M

Pouvez-vous tester celà pour nous ?
Sinon, envoyer des chocolats à l'hébergeur en lui demandant de modifier le fichier php.ini...

a écrit :

Par contre l'image est uploadée sur le server, donc comment faire pour regler ce problème ?

C'est bien étonnant, mais, vous croyant sur parole, pour éviter le message d'erreur, il suffit de préfixer la fonction générant l'erreur (ligne 111) avec "@".
(sous toute réserve)

$source = @imagecreatefromjpeg($fichierSource);

Modifié par GeorgesM (10 Nov 2006 - 10:43)
Vikchill a écrit :
S'il y a un message d'erreur, il faut le corriger, pas le masquer.

+1

Quand à modifier la taille du max upload, cela dépendra de l'hébergeur (ils sont rares ceux qui acceptent)
Modifié par Bison (10 Nov 2006 - 10:58)
merci de votre aide...

j'ai essayé de modifier les directives dans le .htaccess mais rien n'a changer, toujours la même erreur...
alpking a écrit :
merci de votre aide...

j'ai essayé de modifier les directives dans le .htaccess mais rien n'a changer, toujours la même erreur...


Essayer le chocolat...
alpking a écrit :
merci de votre aide...

j'ai essayé de modifier les directives dans le .htaccess mais rien n'a changer, toujours la même erreur...

Il ne te reste qu'à diminuer la taille de ton fichier avant l'upload.
Plus de 2Mo c'est énorme !!!!!
ouai je sais que 2mo c'est deja pas mal, mais c'est un script d'upload pour des amis qui sont très newbie, donc je voulais qu'il n'aie rien d'autre a faire que prendre des photos -> transférer sur leur ordi -> uploader sur le serveur et afficher sur leur site...
Salut, un truc me travaille. Si tu n'as pas accés à la config de PHP comment peux tu avoir en première ligne de code un ini_set??

Parce que sinon, un simple
ini_set('upload_max_filesize', '10M')
ne le ferait pas??

"Bison" a écrit :
Il ne te reste qu'à diminuer la taille de ton fichier avant l'upload.
Plus de 2Mo c'est énorme !!!!!


On peut pas non plus savoir ce que l'utilisateur balance en même temps...
Modifié par coccimaster (10 Nov 2006 - 11:29)
coccimaster a écrit :
On peut pas non plus savoir ce que l'utilisateur balance en même temps...

Oui et alors ?
Si le mec veut transférer 20 Go tu le laisse faire ? Smiley ohwell
Suffit de prévenir c'est tout.

Puis si tu veux de l'upload à outrance suffit de te payer un dédié ! Smiley langue
Youps, en relisant 2-3 docs, je viens de me rendre compte de la grosse c#&§§ que je venais de dire...Mea Culpa!!! Pour le dédié, c'est pas encore dans mes moyens...
Ce n'est pas forcément la taille du fichier qui dépasse 2Mo mais surtout que tu essayes de redimmensionner ton image et que là GD retransforme l'image jpeg en bmp ce qui bouffe plus de 2Mo de mémoire.

J'ai eu le même problème il y a quelques mois ...
a écrit :
orsque j'essaie d'uploader une image (JPG, 2.9MB, 3456x2304 px)

Là elle fait bien plus de 2Mo me semble t'il ? Smiley cligne
Bonjour,
A priori cette erreur est dû au script de redimensionnement de l'image uploadée (et non du poids trop important..)

Il faudrait changer la valeur du "memory_limit" dans le php.ini ou (si vos droits le permettent) de rajouter cette ligne dans le fichier .htaccess :
php_value memory_limit 20M


lien : http://www.sutekidane.net/memo/apache/#memo2

PS : la 1ere ligne de votre script devrait faire la même action, mais suivant la configuration du serveur, il se peut que la fonction ini_set() ne soit pas autorisée...
Modifié par siddhy (10 Nov 2006 - 14:11)
Bonjour,

Je n'est pas ouvert un autre sujet, car je rencontre également le même problème.

Pour les images de trop grandes résolutions, la fonction php ImageCreateFromJpeg renvoie l'erreur :
Fatal error: Allowed memory size of XXXX bytes exhausted (tried to allocate XXX bytes)


Mon hébergeur ne veut pas modifier le php.ini, voila ce qu'il me conseille :

La seule solution possible est d'opter pour un serveur virtuelle ou memory_limit est personnalisable.


c'est assez embétant, il n'y a vraiment aucune autre solution ? (optimiser le code ? 2 boites de chocolat ? ...)