[RESOLU]Content-types et upload d'image - Librairie GD

Content-types et upload d'image - Librairie GD [RESOLU] - PHP - Programmation

Marsh Posté le 15-01-2009 à 11:45:56    

Bonjour à tous,
Décidément c' est pas ma semaine. :pfff:  
 
Voilà j'ai un p'ti soucis. :(  
J'ai un script qui doit enregistrer des infos sur une personne dans une BDD, et dans ces infos il y a aussi une photo dans le formulaire.
(jusque là c'est pas extraordinaire)
 
Alors j'ai créé un petit script, pour l'upload de la photo, qui retaille la photo 2x.
Ce script stocke 1 miniature dans un dossier photo/mini.
Et il stocke l'autre dans un dossier photo/normal
 
Les images sont bien retaillées, et elles sont bien envoyées dans leur dossier respectif.
Sauf que :  
 
J'ai l'impression qu'à la fin de ce script de redimensionnement, le content-type reste bloqué sur image/jpeg.  :pt1cable:  
 
La suite du code ne s'execute pas, la page se fige sur une page blanche avec comme en-tête mapage.php (image JPEG) et affiche l'url de la page que j'ai demandée. :??:  
 
Structure du code :

Code :
  1. /* Content-type */
  2. header('Content-type: image/jpeg');
  3.    redimensionnement();
  4.    déplacement();
  5. /* Content-type */
  6. header('Content-type: text/html');
  7. /* Suite du code */
  8.    affichage_html_divers();
  9.    enregistrement_db();


 
qques lignes de mon phpinfo(); :
-PHP Version 4.3.9
-GD Support enabled  
-GD Version bundled (2.0.28 compatible)
 
Ce script de redimensionnement, je l'ai déjà utilisé pour un autre site et il fonctionne correctement. :heink:  
Si quelqu'un a déjà eu ce problème... ;)  
 
Ju.


Message édité par jocastt le 15-01-2009 à 14:32:39
Reply

Marsh Posté le 15-01-2009 à 11:45:56   

Reply

Marsh Posté le 15-01-2009 à 12:04:18    

Il sert à quoi ton premier Content-Type ? Parce que là il ne sert strictement à rien, si t'affiches de l'HTML après [:pingouino]

Reply

Marsh Posté le 15-01-2009 à 12:07:07    

FlorentG a écrit :

Il sert à quoi ton premier Content-Type ? Parce que là il ne sert strictement à rien, si t'affiches de l'HTML après [:pingouino]


 
Les fonctions de créations d'images via librairie GD ne sont disponibles qu'en content-type image/xxx non ?

Reply

Marsh Posté le 15-01-2009 à 12:08:39    

Nan mais le content-type est destiné au navigateur. Que ce soit PHP ou GD, ils s'en foutent. Ils ne regardent même pas ce header. Ca n'intervient pas du tout dans l'exécution du script, c'est uniquement le navigateur qui l'utilise pour déterminer le type de contenu.

Reply

Marsh Posté le 15-01-2009 à 12:12:21    

FlorentG a écrit :

Nan mais le content-type est destiné au navigateur. Que ce soit PHP ou GD, ils s'en foutent. Ils ne regardent même pas ce header. Ca n'intervient pas du tout dans l'exécution du script, c'est uniquement le navigateur qui l'utilise pour déterminer le type de contenu.


Comment tu peux créer une image jpeg via php sans spécifier une en-tête pendant la création de l'image en question. :??:  
 :non: Je ne suis pas sur que ca soit possible...

Reply

Marsh Posté le 15-01-2009 à 12:16:25    

jocastt a écrit :

Comment tu peux créer une image jpeg via php sans spécifier une en-tête pendant la création de l'image en question. :??:


Tu confonds tout en fait. Les fonctions GD s'en foutent de l'entête. Elles ne savent même pas qu'il existe.

 

L'entête est uniquement utilisé lorsque tu affiches une image, genre :

Code :
  1. header('Content-Type: image/jpeg');
  2. readfile('monimage.jpg');
 

Donc quand tu réceptionnes les données du formulaire, tu fais l'insertion en base, puis le redimensionnement + sauvegarde de l'image, et c'est tout. Mais le redimensionnement ou la sauvegarde s'opèrent sur un fichier, donc il n'y a pas de notion d'HTTP, donc pas d'entête Content-Type

Message cité 1 fois
Message édité par FlorentG le 15-01-2009 à 12:17:08
Reply

Marsh Posté le 15-01-2009 à 12:26:37    

FlorentG a écrit :


Tu confonds tout en fait. Les fonctions GD s'en foutent de l'entête. Elles ne savent même pas qu'il existe.
 
L'entête est uniquement utilisé lorsque tu affiches une image, genre :


Tu pourras donc aisément m'expliquer pourquoi ce code fonctionne :  

Code :
  1. header('Content-type: image/jpeg');
  2. list($width, $height) = getimagesize($img);
  3. $ratio = $width / $height;


Et pourquoi celui là ne fonctionne pas : (Division by zero in xxx.php on line 2)

Code :
  1. list($width, $height) = getimagesize($img);
  2. $ratio = $width / $height;


 :sarcastic:  

Reply

Marsh Posté le 15-01-2009 à 12:28:22    

Euh chez moi ça marche très bien, il n'y a vraiment pas besoin de header. Le problème est ailleurs.
 
Le header n'est pas du tout lu par PHP. Si t'en veux la preuve, je te sors le code source...

Reply

Marsh Posté le 15-01-2009 à 12:29:51    

En fait c'est simple d'ailleurs, le premier ne fonctionne pas non-plus. Mais comme c'est un header différent de text/html, le navigateur n'affiche pas le texte, croyant que c'est une image.

 

Sniff le traffic HTTP, tu verra que le message d'erreur y est aussi


Message édité par FlorentG le 15-01-2009 à 12:30:06
Reply

Marsh Posté le 15-01-2009 à 12:35:10    

Alors je continue de fouiller sur le net en même temps,
voilà une petite page que j'ai trouvée..
 
En haut de chacun de leur script, j'ai l'impression de voir un header.   :sweat:  
 
Par contre, je veux bien voir le code qui génère des images jpeg, sans que l'en-tête jpeg soit appelé. (si ca te dérange pas trop...)

Reply

Marsh Posté le 15-01-2009 à 12:35:10   

Reply

Marsh Posté le 15-01-2009 à 12:38:11    

Si eux mettent un entête en haut, c'est parce qu'ils affichent tout de suite après l'image. Sachant qu'il faut préciser le Content-Type pour que le navigateur sache comme l'afficher.
 
Mais nul besoin de ces entêtes pour redimensionner/sauvegarder une image :) Ton code :

Code :
  1. list($width, $height) = getimagesize($img);
  2. $ratio = $width / $height;


Il faut juste s'assurer que $img contient le chemin vers l'image

Reply

Marsh Posté le 15-01-2009 à 12:42:15    

Purée là je suis perdu, et en plus j'ai faim quoi...
$img contient bien le lien vers l'image en question. Bizarre cette division par 0. :??:  
 
Il faut m'aider ! :p :D
 
Bon, j'ai horreur de faire ca... Mais peut-être l'erreur sautera aux yeux de quelqu'un.

Code :
  1. if (is_uploaded_file($_FILES['photo']['tmp_name'])){
  2. $error = '';
  3. $ftmp  = $_FILES['photo']['tmp_name'];
  4. $fname = (substr(md5(uniqid(rand(), true)),0,6)).(str_replace(' ','_', $_FILES['photo']['name']));
  5. $fname = strtr($fname,'àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ','aaaaaceeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY');
  6. $fname = strtolower($fname);
  7. //extensions autorisées  
  8. $extension_autorises= array('.jpg','.jpeg');
  9. $extension= strrchr($fname,'.');
  10. //lien des photos
  11. $lien    = 'photo/veto/normal/'.$fname;
  12. //dossier miniature
  13. $miniature = 'photo/veto/mini/'.$fname;
  14. /*Definition de la taille max des minatures. */
  15. $width     = 100;
  16. $height    = 100;
  17. $width_n   = 600;
  18. $height_n  = 600;
  19. //verification de l'extension
  20. if (!in_array($extension,$extension_autorises)){
  21.  $error .= 'Le fichier n\'est pas une image';
  22. }
  23. if (!move_uploaded_file($ftmp,$lien)){
  24.  $error .= 'Impossible de copier le fichier';
  25. }
  26.         /* Content type */
  27.         header('Content-type: image/jpeg');
  28.         /*creation des miniatures. */
  29. list($width_orig, $height_orig) = getimagesize($lien);
  30. // On stoppe le script si la taille de la photo est trop grande
  31. if ($width_orig > 1000 || $height_orig > 1000){
  32.  exit('L\'image1 est trop grande <br /><a href="javascript:history.back();">retour</a><br />'.$rappel.' <hr />');
  33. }
  34. $ratio_orig   = $width_orig/$height_orig;
  35. // Ratio miniature
  36. if ($width_max/$height_max > $ratio_orig){
  37.  $width    = $height*$ratio_orig;
  38. }else{
  39.  $height   = $width/$ratio_orig;
  40. }
  41. // Ratio normal
  42. if ($width_orig > $width_n || $height_orig > $height_n){
  43.  if ($width_n/$height_n > $ratio_orig){
  44.   $width_n  = $height_n*$ratio_orig;
  45.  }else{
  46.   $height_n = $width_n/$ratio_orig;
  47.  }
  48. }else{
  49.  $width_n = $width_orig;
  50.  $height_n = $height_orig;
  51. }
  52. // Config miniature
  53. $image_p   = imagecreatetruecolor($width,$height);
  54. $image    = imagecreatefromjpeg($lien);
  55. imagecopyresampled($image_p,$image,0,0,0,0,$width, $height, $width_orig, $height_orig);
  56. // Config normale
  57. $image_p_n    = imagecreatetruecolor($width_n,$height_n);
  58. $image_n      = imagecreatefromjpeg($lien);
  59. imagecopyresampled($image_p_n,$image_n,0,0,0,0,$width_n, $height_n, $width_orig, $height_orig);
  60. //movance  de la miniature crée au dessus dans le repertoire miniature  
  61. imagejpeg($image_p,$miniature,90);
  62. //movance  de la miniature crée au dessus dans le repertoire normal  
  63. imagejpeg($image_p_n,$lien,90);
  64. imagejpeg($image_p);
  65. unset($miniature);
  66. unset($image_p);
  67. unset($image_p_n);
  68. unset($lien);
  69. unset($image);
  70. unset($width);
  71. unset($height);
  72. unset($image_n);
  73. unset($width_n);
  74. unset($height_n);
  75. unset($ratio_orig);
  76. }else{
  77. $fname='';
  78. }


 
 :sweat: désolé.


Message édité par jocastt le 15-01-2009 à 13:16:31
Reply

Marsh Posté le 15-01-2009 à 14:01:02    

Ton code là :

Code :
  1. list($width_orig, $height_orig) = getimagesize($lien);


$lien doit être le fichier image, là c'est totalement autre chose. Il faut remplace par :
 

Code :
  1. list($width_orig, $height_orig) = getimagesize($_FILES['photo']['tmp_name']);


 
Et pareil après dans l'appel à imagecreatefromjpeg.
 
Aussi, la validation du type d'image (basée sur l'extension) n'est pas bonne et dangereuse. N'importe qui peut renommer un fichier en .jpg. Pareil si l'image est invalide. Il faut plutôt vérifier le type retourné par getimagesize

Reply

Marsh Posté le 15-01-2009 à 14:23:11    

FlorentG a écrit :

Ton code là :

Code :
  1. list($width_orig, $height_orig) = getimagesize($lien);


$lien doit être le fichier image, là c'est totalement autre chose. Il faut remplace par :

Code :
  1. list($width_orig, $height_orig) = getimagesize($_FILES['photo']['tmp_name']);




 
un echo de <img src=$lien /> m'affiche bien l'image uploadée.
(car je bouge le fichier temp vers le dossier de mon choix grace a move_uploaded_file)
Donc $lien contient bien le lien relatif de mon image. :(  
 
Merci pour ton aide en tout cas. Je commence à perdre espoir. :pfff:  
Question sécurité, tu as tout à fait raison et je me pencherai sur la question dès que ce contre temps sera reglé.
 
Si quelqu'un voit ce qui cloche..., qu'il n'hésite pas :s

Reply

Marsh Posté le 15-01-2009 à 14:24:12    

Peut-être avec un chemin absolu plutôt que relatif ? Ce n'est pas sûr que getimagesize gère tout ce qui est include path et tout.

Reply

Marsh Posté le 15-01-2009 à 14:29:27    

FlorentG a écrit :

Peut-être avec un chemin absolu plutôt que relatif ? Ce n'est pas sûr que getimagesize gère tout ce qui est include path et tout.


Laisse tomber je viens de voir mon erreur. Ca devient grave... Regarde ligne 49. 2 variables qui ne sont pas déclarées . . . :o  
Comment perdre 2 heures pour une connerie pareille :lol:  
 
Ca me rend dingue tout ca. :cry:  
 
En tout cas merci pour ton aide.
 
PS : Bizarrement ca fonctionne beaucoup mieux comme ca. :hello:  :hello:


Message édité par jocastt le 15-01-2009 à 14:31:39
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed