8800 sujets

Développement web côté serveur, CMS

Bonjour,

J'ai un script PHP qui envoie un mail avec une image en pièce jointe.

Lors de la réception du mail, aucun problème avec Gmail, mais impossible d'ouvrir l'image avec Hotmail ou Outlook après l'avoir téléchargée :
- "Aucun aperçu disponible" avec la visionneuse windows
- "Erreur d'interprétation du fichier d'image JPEG" sous Ubuntu.

Voici le script :

$boundary = "-----=".md5(uniqid(rand()));

	$header = "MIME-Version: 1.0\r\n";
	$header .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\r\n";
	
	$pj = "plan_acces.jpg";

	$piecejointe = "--".$boundary."\r\n";
	$piecejointe .= 'Content-Type: image/jpeg; name="'.$pj.'"'."\n";
	$piecejointe .= 'Content-Transfer-Encoding: base64'."\n";
	$piecejointe .= 'Content-Disposition:attachement; filename="'.$pj.'"'."\n\n";
	$piecejointe .= "Content-ID: <image1>\r\n\r\n";
	$piecejointe .= chunk_split(base64_encode(file_get_contents($pj)));
	$piecejointe .= "\r\n\r\n";
	$piecejointe .= "--".$boundary."\r\n";
	
	$corps = "--".$boundary."\r\n";
	$corps .= 'Content-type: text/html; charset= iso-8859-1'.'\r\n';
	$corps .= "Content-Transfer-Encoding: 8bit\n\n"; 
	$corps .= stripslashes($_POST['corps'])."\r\n";
	$corps .= $piecejointe;
	
	$dest = "*********************";	//test email
	
	if(mail($dest, $_POST['objet'], $corps, $header))
		$confirm .= "<p>L'email a bien &eacute;t&eacute; envoy&eacute;.</p>";
	else $confirm .= "<p>Erreur lors de l'envoi de l'email.</p>";


Je n'ai pas bien saisi l'utilisation des boundaries, l'erreur vient peut-être de là.

Merci d'avance,

Romain
Modifié par RomainDumay (05 Sep 2011 - 15:33)
Regarde déjà du côté de tes fins de ligne, les ennuies viennent souvent de là et dans ton code c'est du grand n'importe quoi. Une fin de ligne dans un entête de mail c'est une et une seule occurrence de "\r\n" (CRLF) et rien d'autre, toi tu as des "\n\n", "\r\n\r\n", etc.

Sources : RFC 1896, RFC 2045, RFC 2046, RFC 2047, RFC 2048, RFC 2049, RFC 2822.
Modifié par jb_gfx (02 Sep 2011 - 18:03)
Modérateur
@jb_gfx : +1 !

@RomainDumay : Le boundary sert à rendre ton mail unique. C'est la raison pour laquelle, il y a un uniquid entres autres. Bien que tu veuilles envoyer un mail avec pièce jointe, il y a toujours un texte qui l’accompagne. Le texte peut être en html bien sûr. Là dans ton code, je ne vois pas l'alternative textuelle (html et text). Smiley biggol
Modifié par niuxe (03 Sep 2011 - 10:17)
Maintenant j'ai la pièce jointe, mais pas le texte :

$boundary = "-----=".md5(uniqid(rand()));

	$header = "MIME-Version: 1.0\r\n";
	$header .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\r\n";
	
	$corps = "--".$boundary."\r\n";
	$corps .= "Content-Type: text/html; charset='iso-8859-1'\r\n";
	$corps .= "Content-Transfer-Encoding: 8bit\r\n"; 
	$corps .= stripslashes($_POST['corps'])."\r\n";
	$corps .= "--".$boundary."\r\n";
	
	$piecejointe = "--".$boundary."\r\n";
	$piecejointe .= "Content-Type: image/jpeg; name='plan_acces.jpg'\r\n";
	$piecejointe .= "Content-Transfer-Encoding: base64\r\n";
	$piecejointe .= "Content-Disposition:attachement; filename='plan_acces.jpg'\r\n";
	$piecejointe .= "Content-ID: <image1>\r\n\r\n";
	$piecejointe .= chunk_split(base64_encode(file_get_contents('plan_acces.jpg')))."\r\n";
	$piecejointe .= "--".$boundary."\r\n";	
	$corps .= $piecejointe;
	
	$dest = "*****************";	//test email
	
	if(mail($dest, $_POST['objet'], $corps, $header))
		$confirm .= "<p>L'email a bien &eacute;t&eacute; envoy&eacute;.</p>";
	else $confirm .= "<p>Erreur lors de l'envoi de l'email.</p>";

Modifié par RomainDumay (05 Sep 2011 - 12:50)
niuxe a écrit :
@jb_gfx : +1 !

@RomainDumay : Le boundary sert à rendre ton mail unique. C'est la raison pour laquelle, il y a un uniquid entres autres. Bien que tu veuilles envoyer un mail avec pièce jointe, il y a toujours un texte qui l’accompagne. Le texte peut être en html bien sûr. Là dans ton code, je ne vois pas l'alternative textuelle (html et text). Smiley biggol


Comment faut-il ajouter une alternative textuelle ?
Tu peux tester ça ?


$boundary = md5(uniqid(rand()));

$header = "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\r\n";

$msg = "--$boundary\r\n";
$msg .= "Content-Type: text/html; charset='iso-8859-1'\r\n";
$msg .= "Content-Transfer-Encoding: 8bit\r\n"; 
$msg .= nl2br(stripslashes($_POST['corps']));
$msg .= ."\r\n\r\n";
$msg .= "--$boundary\r\n";
$msg .= "Content-Type: image/jpeg; name='plan_acces.jpg'\r\n";
$msg .= "Content-Transfer-Encoding: base64\r\n";
$msg .= "Content-Disposition:attachement; filename='plan_acces.jpg'\r\n";
$msg .= "Content-ID: <image1>\r\n\r\n";
$msg .= chunk_split(base64_encode(file_get_contents('plan_acces.jpg')))."\r\n\r\n";
$msg .= "--$boundary--";

$dest = "*****************";	//test email

if (mail($dest, $_POST['objet'], $msg, $header))
$confirm .= "<p>L'email a bien &eacute;t&eacute; envoy&eacute;.</p>";
else
$confirm .= "<p>Erreur lors de l'envoi de l'email.</p>";
jb_gfx a écrit :
Tu peux tester ça ?


J'ai encore que la pièce jointe, mais pas le texte.
Modifié par RomainDumay (05 Sep 2011 - 15:14)
C'est pas normal. Tu es sûr que $_POST['corps'] contient bien un texte ?
Modifié par jb_gfx (05 Sep 2011 - 15:20)
C'est bon avec "\r\n\r\n" avant la ligne "$msg .= nl2br(stripslashes($_POST['corps']));" (à la place de "\r\n").
Je ne comprend pas trop pourquoi mais tout fonctionne maintenant.

Merci pour votre aide.
Modifié par RomainDumay (05 Sep 2011 - 15:33)
Ah ben oui il insérer une ligne vide entre les parties représentant les entêtes et les données elles mêmes (et après aussi). Maintenant que tu sais faire tu peux utiliser la bibliothèque PHPMailer. Smiley smile
Modifié par jb_gfx (05 Sep 2011 - 15:48)