web-dev-qa-db-fra.com

Simple PHP: Pièce jointe à un e-mail (code golf)

Imaginez un utilisateur qui aimerait mettre un formulaire sur son site Web qui permettrait à un visiteur du site Web de télécharger un fichier et un simple message, qui sera immédiatement envoyé par e-mail (c'est-à-dire que le fichier n'est pas stocké sur le serveur, ou s'il l'est uniquement temporairement) en tant que pièce jointe avec la note dans le corps du message.

Voir plus de détails sur http://a2zsollution.com/php-secure-e-mail/

Quelle est la manière la plus simple d'y parvenir?

Le plus simple en termes de:

  • Taille (code golf)
  • Facilité de mise en œuvre (idéalement tout dans un seul fichier, nécessite peu ou pas de ressources externes)
  • Non obscurci pour le plaisir de l'obscurcissement (les compromis pour la taille sont très bien)
  • Exemple autonome (s'il est appelé sans publication de formulaire, il affiche le formulaire)

C'est presque l'inverse de: Comment obtenir des e-mails et leurs pièces jointes à partir de PHP . Il aurait presque pu être répondu en Compilation de courriels avec plusieurs pièces jointes en PHP , mais il n'affiche pas réellement le code.

24
Adam Davis

Juste pour le plaisir, je pensais que je le frapperais. Cela a fini par être plus compliqué que je ne le pensais parce que je ne comprenais pas complètement comment fonctionnait la partie limite, j'ai finalement compris que le début et la fin "-" étaient importants et c'est parti.

<?php
    if(isset($_POST['submit']))
    {
        //The form has been submitted, prep a Nice thank you message
        $output = '<h1>Thanks for your file and message!</h1>';
        //Set the form flag to no display (cheap way!)
        $flags = 'style="display:none;"';

        //Deal with the email
        $to = '[email protected]';
        $subject = 'a file for you';

        $message = strip_tags($_POST['message']);
        $attachment = chunk_split(base64_encode(file_get_contents($_FILES['file']['tmp_name'])));
        $filename = $_FILES['file']['name'];

        $boundary =md5(date('r', time())); 

        $headers = "From: [email protected]\r\nReply-To: [email protected]";
        $headers .= "\r\nMIME-Version: 1.0\r\nContent-Type: multipart/mixed; boundary=\"_1_$boundary\"";

        $message="This is a multi-part message in MIME format.

--_1_$boundary
Content-Type: multipart/alternative; boundary=\"_2_$boundary\"

--_2_$boundary
Content-Type: text/plain; charset=\"iso-8859-1\"
Content-Transfer-Encoding: 7bit

$message

--_2_$boundary--
--_1_$boundary
Content-Type: application/octet-stream; name=\"$filename\" 
Content-Transfer-Encoding: base64 
Content-Disposition: attachment 

$attachment
--_1_$boundary--";

        mail($to, $subject, $message, $headers);
    }
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>MailFile</title>
</head>

<body>

<?php echo $output; ?>

<form enctype="multipart/form-data" action="<?php echo $_SERVER['PHP_SELF'];?>" method="post" <?php echo $flags;?>>
<p><label for="message">Message</label> <textarea name="message" id="message" cols="20" rows="8"></textarea></p>
<p><label for="file">File</label> <input type="file" name="file" id="file"></p>
<p><input type="submit" name="submit" id="submit" value="send"></p>
</form>
</body>
</html>

Très barebones vraiment, et évidemment l'utilisation de CSS en ligne pour masquer le formulaire est un peu bon marché et vous voudriez presque certainement un peu plus de commentaires à l'utilisateur! En outre, je passerais probablement un peu plus de temps à déterminer le type de contenu réel du fichier, plutôt que de tricher et d'utiliser l'application/octet-stream, mais cette partie est tout aussi intéressante.

71
MalphasWats

Une combinaison de cela http://www.webcheatsheet.com/PHP/send_email_text_html_attachment.php#attachment

avec l'exemple de fichier de téléchargement php fonctionnerait. Dans l'exemple de téléchargement de fichier au lieu d'utiliser move_uploaded_file pour le déplacer du dossier temporaire, vous devez simplement l'ouvrir:

$attachment = chunk_split(base64_encode(file_get_contents($tmp_file))); 

$tmp_file = $_FILES['userfile']['tmp_name'];

et l'envoyer en pièce jointe comme le reste de l'exemple.

Tout en un seul fichier/autonome:

<? if(isset($_POST['submit'])){
//process and email
}else{
//display form
}
?>

Je pense que c'est un exercice rapide pour obtenir ce dont vous avez besoin en fonction des deux exemples disponibles ci-dessus.

P.S. Il doit être téléchargé quelque part avant qu'Apache ne le transmette à PHP pour faire ce qu'il veut avec. Ce serait le dossier temporaire de votre système par défaut, sauf s'il a été modifié dans le fichier de configuration.

16
Nael El Shawwa

Afin d'ajouter le fichier à l'e-mail en tant que pièce jointe, il devra être stocké brièvement sur le serveur. Il est cependant trivial de le placer dans un emplacement tmp puis de le supprimer une fois que vous en avez terminé.

En ce qui concerne les e-mails, Zend Mail possède une interface très facile à utiliser pour traiter les pièces jointes des e-mails. Nous fonctionnons avec tout le Zend Framework installé, mais je suis sûr que vous pouvez simplement installer la bibliothèque Zend_Mail sans avoir besoin d'autres modules pour les dépendances.

Avec Zend_Mail, envoyer un e-mail avec une pièce jointe est aussi simple que:

$mail = new Zend_Mail();
$mail->setSubject("My Email with Attachment");
$mail->addTo("[email protected]");
$mail->setBodyText("Look at the attachment");
$attachment = $mail->createAttachment(file_get_contents('/path/to/file'));
$mail->send();

Si vous cherchez un package à un fichier pour faire tout le formulaire/e-mail/pièce jointe, je n'en ai pas vu un. Mais les composants individuels sont certainement disponibles et faciles à assembler. La chose la plus délicate de tout le groupe est la pièce jointe, que la recommandation ci-dessus rend très simple.

4
Moot

Je n'ai pas testé la partie e-mail de cela (ma boîte de test n'envoie pas d'e-mail) mais je pense que cela fonctionnera.

<?php
if ($_POST) {
$s = md5(Rand());
mail('[email protected]', 'attachment', "--$s

{$_POST['m']}
--$s
Content-Type: application/octet-stream; name=\"f\"
Content-Transfer-Encoding: base64
Content-Disposition: attachment

".chunk_split(base64_encode(join(file($_FILES['f']['tmp_name']))))."
--$s--", "MIME-Version: 1.0\r\nContent-Type: multipart/mixed; boundary=\"$s\"");
exit;
}
?>
<form method="post" enctype="multipart/form-data" action="<?php echo $_SERVER['PHP_SELF'] ?>">
<textarea name="m"></textarea><br>
<input type="file" name="f"/><br>
<input type="submit">
</form>
4
mcrumley

Cet article " Comment créer PHP avec pièce jointe " présente des instructions étape par étape sur la façon de répondre à vos besoins.

Citation:

Cet article vous montre comment créer un formulaire de courrier électronique basé sur PHP qui prend en charge la pièce jointe. L'article vous montrera également comment valider le type et la taille du fichier téléchargé.

Il comprend les étapes suivantes:

  • Le formulaire HTML avec boîte de téléchargement de fichier
  • Récupérer le fichier téléchargé dans le script PHP
  • Validation de la taille et de l'extension du fichier téléchargé
  • Copiez le fichier téléchargé
  • Envoi de l'e-mail

Le code d'exemple complet peut être téléchargé ici

4
Adrian

PEAR :: Mail_Mime ? Bien sûr, PEAR dépendance de (min) 2 fichiers (juste mail_mime lui-même si vous le modifiez pour supprimer les dépendances de pear), mais cela fonctionne bien. De plus, la plupart des serveurs ont PEAR installé dans une certaine mesure, et dans le meilleur des cas, ils ont Pear/Mail et Pear/Mail_Mime. Quelque chose qui ne peut pas être dit pour la plupart des autres bibliothèques offrant les mêmes fonctionnalités.

Vous pouvez également envisager de chercher dans PHP extension IMAP . C'est un peu plus compliqué et nécessite plus de configuration (non activé ou installé par défaut), mais il doit être plus efficace pour compiler et envoyer des messages à un serveur compatible IMAP.

1
Kevin Peno