Mails et deux pieces jointes php

Répondre
wixar
le 06/06/2007 à 09:05
wixar
bonjour à tous
j'ai fait un formulaire pour envoyer deux pieces jointes

le seul problème c'est que la deuxième pièce jointe ne pars pas

quelqu'un aurait une idée?

[taille=grand][couleur=rouge]LA PARTIE PROG [/couleur](code tronqué)[/taille]

Code : PHP
<?php


$email= $_POST['Email'];

$destinataire = "darkcyr@hotmail.fr"; # email de destination




#----------------------------------# options de pièce jointe------------------------------------#


$rep = "upload/"; # répertoire temporaire d'upload

$taillemax = 10240000; # taille max de la pièce jointe (multiple de 1024)


$erreur = false; // pas encore d'érreur

$message = false; //pas encore de message

$focus = 0; //pour la surbrillance

#----------------------------------------------------------------------------------------------------#


if (!empty($_POST)) #si le formulaire n'est pas vide


$piecejointe = "";# pièce jointe

if(!$erreur && strlen($_FILES['Fichier']['name']))
{
$fichier = $_FILES['Fichier'];

#---------------------------------upload du fichier sur le serveur------------------------------------#

$temp = $fichier['tmp_name'];
$name = $fichier['name'];
$size = $fichier['size'];
$destination = $rep.$name;

if($size > $taillemax)
$erreur = "Taille du fichier $name > ".(int)($taillemax/1024)." Ko";

elseif(!@is_uploaded_file($temp))
$erreur = "Téléchargement de $name impossible";

elseif(!@move_uploaded_file($temp, $destination))
$erreur = "Problème de transfert de $name";

if($erreur) $focus = 7;

else
{
#---------------------------------lecture et conversion du fichier------------------------------------#

if($openf = @fopen($destination, "rb"))
{
$fichier = fread($openf, filesize($destination));
@fclose($openf);

#--------------------------------- encodage norme RFC 2045------------------------------------#

$piecejointe = chunk_split(base64_encode($fichier));
}
else
{
$erreur = "Problème de lecture du fichier $name";
$focus = 7;
}
}

}


$piecejointe2 = "";# pièce jointe

if(!$erreur && strlen($_FILES['Fichier2']['name']))
{
$fichier2 = $_FILES['Fichier2'];

#---------------------------------upload du fichier sur le serveur------------------------------------#

$temp2 = $fichier2['tmp_name'];
$name2 = $fichier2['name'];
$size2 = $fichier2['size'];
$destination2 = $rep.$name2;

if($size2 > $taillemax)
$erreur = "Taille du fichier $name2 > ".(int)($taillemax/1024)." Ko";

elseif(!@is_uploaded_file($temp2))
$erreur = "Téléchargement de $name2 impossible";

elseif(!@move_uploaded_file($temp2, $destination2))
$erreur = "Problème de transfert de $name2";

if($erreur) $focus = 7;

else
{
#---------------------------------lecture et conversion du fichier------------------------------------#

if($openf = @fopen($destination2, "rb"))
{
$fichier2 = fread($openf, filesize($destination2));
@fclose($openf);

#--------------------------------- encodage norme RFC 2045------------------------------------#

$piecejointe2 = chunk_split(base64_encode($fichier2));
}
else
{
$erreur = "Problème de lecture du fichier $name2";
$focus = 7;
}
}

}



if(!$erreur) # pas d'erreur donc on continue
{
#--------------------------------- traitement du tableau $_POST qui contient les paires name => value-----------------------------------#

$message_final = "";

foreach($_POST as $key => $value)
{
# la deuxième partie du test passe les champs non désirés dans le mail // pour passer d'autres champs les séparer par |

if (strlen($value) && !eregi("(MAX_FILE_SIZE)", $key))
$message_final .= "$key : ".strip_tags($value)."\n";

}

# formatage du message de confirmation affiché

$message = ereg_replace("(\n|\r|\r\n)", "<br>", htmlentities($message_final)); # conversion des sauts de ligne et des caractères spéciaux


$objet = "$entete ".$_POST['Objet'];

# si l'email n'est pas renseigné on le remplace par celui du destinataire, en ajoutant une alerte au message
$final_mail = $_POST['Email'];

if(empty($_POST['Email']))
{
$final_mail = $destinataire;
$message_final .= "\nNe pas répondre par mail : email absent.\n";
}
# en-têtes
$headers = "From: ".$final_mail;
if(strlen($email_cc))
$headers .= "\nCC: ".$email_cc;
if(strlen($email_bcc))
$headers .= "\nBCC: ".$email_bcc;

# si pièce jointe on ajoute l'en-tête spécifique avec séparateurs
if(strlen($piecejointe) || strlen($piecejointe2))
{
$boundary = "/-------".md5(uniqid(rand()))."-------/"; // séparateur
$headers .= "\nMIME-Version: 1.0\nContent-Type: multipart/mixed; boundary=\"$boundary\"\n";
$message_final =
"This is a multi-part message in MIME format.\n--$boundary\n".
"Content-Type: text/plain; charset=ISO-8859-1\n".
"Content-Transfer-Encoding: 7bit\n\n".
"$message_final\n\n--$boundary\n".
"Content-Type: $mimetype; name=\"$name\"\n".
"Content-Transfer-Encoding: base64\n".
"Content-Disposition: attachment; filename=\"$name\"\n\n".
"$piecejointe\n--".
"Content-Type: $mimetype; name=\"$name2\"\n".
"Content-Transfer-Encoding: base64\n".
"Content-Disposition: attachment; filename=\"$name2\"\n\n".
"$piecejointe2\n--".

$boundary."--\n";
}

# envoi du mail
if (@mail($destinataire, stripslashes($objet), stripslashes($message_final), $headers))
{
@unlink($destination); // suppression de la pièce jointe
@unlink($destination2); // suppression de la pièce jointe

$pageName = "Le mail a été envoyé !";
}
else
{
$pageName = "Echec !";
$erreur = "Echec de l'envoi ! Merci d'essayer encore SVP";
}

}
else {

$pageName = "Erreur de saisie !";

} // if(!$erreur)

}
else {

$_POST = false;

} // if ($_POST)
?>


[taille=grand][couleur=rouge]LE FORMULAIRE (enfin juste la partie avec les pièces jointes)[/couleur](code tronqué)[/taille]



Code : PHP

<form name="formulaire" action="<? echo $_SERVER['PHP_SELF']?>" method="post" enctype="multipart/form-data">
<?if (file_exists($rep)) { ?>
<p>
<label for="fichier">CV</label><input type="hidden" name="MAX_FILE_SIZE" value="<? echo $taillemax?>"/><input type="file" maxlength="60" id="fichier" <? if($focus == 7) echo "class=\"focus\"";?> name="Fichier"/>
<p>
<label for="fichier2">Lettre de motivation</label><input type="hidden" name="MAX_FILE_SIZE" value="<? echo $taillemax?>"/><input type="file" maxlength="60" id="fichier2" <? if($focus == 7) echo "class=\"focus\"";?> name="Fichier2"/>


<? } ?>

<input id="submit" type="submit" value="Envoyer"/><br/>

</p>
</form>
LA GLOBULE
le 06/06/2007 à 10:17
LA GLOBULE
Tu dois avoir un problème de séparateur de parties de mail.
Je suis au boulot là, je regarderais ce soir, et je trouverais la solution (j'ai dev un webmail, et j'ai assez galéré avec ces trucs la :p).
wixar
le 06/06/2007 à 10:43
wixar
merci :)

je pense aussi que le probleme vient de la

parce que si dans

<php?

# if(strlen($piecejointe) || strlen($piecejointe2))
# {
# $boundary = "/-------".md5(uniqid(rand()))."-------/"; // séparateur
# $headers .= "\nMIME-Version:1.0\nContent-Type:multipart/mixed;boundary=\"$boundary\"\n";
# $message_final =
# "This is a multi-part message in MIME format.\n--$boundary\n".
# "Content-Type: text/plain; charset=ISO-8859-1\n".
# "Content-Transfer-Encoding: 7bit\n\n".
# "$message_final\n\n--$boundary\n".
# "Content-Type:$mimetype;name=\"$name\"\n".
# "Content-Transfer-Encoding: base64\n".
# "Content-Disposition:attachment;filename=\"$name\"\n\n".
# "$piecejointe\n--".
# "Content-Type:$mimetype;name=\"$name2\"\n".
# "Content-Transfer-Encoding: base64\n".
# "Content-Disposition:attachment;filename=\"$name2\"\n\n".
# "$piecejointe2\n--".
#
# $boundary."--\n";
# } ?>


si j'enleve les 4 lignes à partir de content type, c'est la deuxieme pj qui part.

pour la séparation, j'ai tenté
<php?# si pièce jointe on ajoute l'en-tête spécifique avec séparateurs
if(strlen($piecejointe) || strlen($piecejointe2))
{
$boundary = "/-------".md5(uniqid(rand()))."-------/"; // séparateur
$headers .= "\nMIME-Version: 1.0\nContent-Type: multipart/mixed; boundary=\"$boundary\"\n";
$message_final =
"This is a multi-part message in MIME format.\n--$boundary\n".
"Content-Type: text/plain; charset=ISO-8859-1\n".
"Content-Transfer-Encoding: 7bit\n\n".
"$message_final\n\n--$boundary\n".
"Content-Type: $mimetype;

name=\"$name\"\n".
"Content-Transfer-Encoding: base64\n".
"Content-Disposition: attachment;
filename=\"$name\"\n\n".
"$piecejointe\n--".
$boundary."--\n".
"Content-Type: $mimetype;


name=\"$name2\"\n".
"Content-Transfer-Encoding: base64\n".
"Content-Disposition: attachment;
filename=\"$name2\"\n\n".
"$piecejointe2\n--".
$boundary."--\n";

}?>


mais rien n'y fait

merci d'avance pour ton aide, je galère depuis pas mal de temps :(

en plus je suis très mauvais en php ^^ mais stage oblige ^^

si tu veux un apercu de l'utilisation:
http://www.copie-est.com/postuler.php
Bzh
le 06/06/2007 à 12:20
Bzh
Attention aux injections d'entetes mail !

# $objet = "$entete ".$_POST['Objet'];  
#
# # si l'email n'est pas renseigné on le remplace par celui du destinataire, en ajoutant une alerte au message
# $final_mail = $_POST['Email'];
#
# if(empty($_POST['Email']))
# {
# $final_mail = $destinataire;
# $message_final .= "\nNe pas répondre par mail : email absent.\n";
# }
# # en-têtes
# $headers = "From: ".$final_mail;
# if(strlen($email_cc))
# $headers .= "\nCC: ".$email_cc;
# if(strlen($email_bcc))
# $headers .= "\nBCC: ".$email_bcc;


Je n'arrive pas à trouver où tu vérifies tes entrées !
wixar
le 06/06/2007 à 14:16
wixar
vu que je suis débutant en php, ca ne doit pas etre fait ^^

y a til des scripts tout fait pour les vérifier?
LA GLOBULE
le 06/06/2007 à 20:25
LA GLOBULE
Oui, donc, je note 3 problèmes au code de ton mail :

1) tu dis que ton mail a un Content-Type de type text/plain. Ce qui faux car tu as du texte plus deux attachements. Pour forger ce genre de mail, il faut faire une partie multipart/mixed qui contiendra ta partie text/plain plus les deux parties de tes pièces jointes.

2) il te manque un séparateur ($boundary) entre tes deux pièces jointes.

3) tu mets un "\n--" juste après ta première pièce jointe, or ce "\n--" marque la fin d'une part, donc il doit se mettre uniquement après ta seconde pièce jointe.

A part çà, je ne vois pas d'erreur.

Voilou :)

PS : si tu galères de trop, j'ai dev une lib qui permet d'envoyer des mails avec des parties texte ou texte / html + un nombre variable de pièces jointes, le tout en base64. C'est comme tu veux.

PPS : ce genre de code à l'air chiant à faire, mais le plus simple, c'est de prendre un thunderbird et de s'envoyer à soi-meme des mails "tests" puis de regarder le code source du mail généré par thunderbird et de le reproduire en PHP (car thunderbird respecte assez bien la RFC 822 pour l'écriture des mails).
LA GLOBULE
le 06/06/2007 à 20:34
LA GLOBULE
y a til des scripts tout fait pour les vérifier?


Pas vraiment.
Pour des mails, tu dois surtout faire attention aux \n et aux \r\n dans les adresses emails (expediteur, destinataire, cc, cci) ou le titre du mail. Tout ce qui est entete en fait.

Car si tu permets ces caractères, n'importe qui peut utiliser ton formulaire (si ton mail est bien envoyé via un formulaire html) et forger ses propres entêtes et donc spammer la terre entière (avec ton hébergement web :/).
wixar
le 07/06/2007 à 08:43
wixar
Merci la globule, deux erreurs corrigées mais rien n'y fait :(

voici le code modif

<php?# si pièce jointe on ajoute l'en-tête spécifique avec séparateurs
if(strlen($piecejointe) || strlen($piecejointe2))
{
$boundary = "/-------".md5(uniqid(rand()))."-------/"; // séparateur
$headers .= "\nMIME-Version: 1.0\nContent-Type: multipart/mixed; boundary=\"$boundary\"\n";
$message_final =
"This is a multi-part message in MIME format.\n--$boundary\n".
"Content-Type: multipart/mixed ; charset=ISO-8859-1\n".
"Content-Transfer-Encoding: 7bit\n\n".
"$message_final\n\n--$boundary\n".
"Content-Type: $mimetype;

name=\"$name\"\n".
"Content-Transfer-Encoding: base64\n".
"Content-Disposition: attachment;
filename=\"$name\"\n\n".
"$piecejointe\n".
$boundary."\n".
"Content-Type: $mimetype;


name=\"$name2\"\n".
"Content-Transfer-Encoding: base64\n".
"Content-Disposition: attachment;
filename=\"$name2\"\n\n".
"$piecejointe2\n--".
$boundary."--\n";

}
?>
LA GLOBULE
le 07/06/2007 à 10:06
LA GLOBULE
Ah oui, mais ca n'est toujours pas bon la :)

Tu as oublié de déclarer une partie texte juste après ton multipart/mixed.

Je te passe ma classe PHP si ca peut t'aider.

PS : la fonction internet_address_parse_string($adresse) n'est pas définie dans ma classe, mais c'est simplement une fonction qui valide l'adresse email passée en argument.
wixar
le 07/06/2007 à 13:37
wixar
je t'avouerais que je suis assez mauvais en php
mais je ne vois pas comment encore rajouter la déclaration de la partie texte apres le multipart
pourrais tu m'aider?

merci d'avance ;)
Répondre
LoadingChargement en cours