[RESOLU] Phpmailer pour mail avec pièce jointe

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : [RESOLU] Phpmailer pour mail avec pièce jointe

Re: Phpmailer pour mail avec pièce jointe

par la_belette » 18 juil. 2019, 12:53

Merci Saian ! Effectivement, si on ne fait pas d'echo, ça ne fonctionne pas !

Voici donc le code qui fonctionne pour ceux qui veulent un formulaire de ce genre avec phpmailer:
<?php
include"header.php";
use PHPMailer\PHPMailer\PHPMailer;
if (isset($_POST['sendmail'])) {

    if (isset($_FILES["userfile"]) && $_FILES['userfile']['name'] != "") {
        $nom_fichier = $_FILES['userfile']['name'];
        $source = $_FILES['userfile']['tmp_name'];
        $type_fichier = $_FILES['userfile']['type'];
        $taille_fichier = $_FILES['userfile']['size'];

        if ($nom_fichier != ".htaccess") {
            if ($type_fichier == "image/jpeg"
                || $type_fichier == "image/pjpeg"
                || $type_fichier == "application/pdf") {


                if (array_key_exists('userfile', $_FILES)) {
                    $uploadfile = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['userfile']['name']));
                    if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
                        $msg = '';
                        require '../phpmailer/src/PHPMailer.php';
                        $mail = new PHPMailer;
                        $mail->setFrom($_POST['email'], $_POST['name']);
                        $mail->addAddress('[email protected]');
                        $mail->Subject = $_POST['offre'];
                        $mail->Body = $_POST['message'];
                        // Attach the uploaded file
                        $mail->addAttachment($uploadfile,$nom_fichier);
                        if (!$mail->send()) {
                            $msg .= "Mailer Error: " . $mail->ErrorInfo;
                        } else {
                            $msg .= "Message envoyé!";
                        }
                    } else {
                        $msg .= 'Failed to move file to ' . $uploadfile;
                    }
                }
            }
        }
    }
    if (isset($msg)){
echo $msg
}
    else{
echo "Votre mail n'a pas été envoyé. Vérifiez que votre pièce jointe est bien un pdf ou un jpeg";
}
}
?>
<form enctype="multipart/form-data" action="testmail.php" method="post">
    <table>
        <tr>
            <td><label for="nom">Votre nom<div style="color:red;display:inline;">*</div> :</label></td>
            <td><input type="text" name="name" required/></td>
        </tr>
        <tr>
            <td><label for="email">Votre E-mail<div style="color:red;display:inline;">*</div> :</label></td>
            <td><input type="email" name="email" required/></td>
        </tr>
        <tr>
            <td>Votre offre<div style="color:red;display:inline;">*</div> :</td>
            <td><input type="text" name="offre" required/></td>
        </tr>
        <tr>
            <td><label for="message">Vos motivations<div style="color:red;display:inline;">*</div> :</label></td>
            <td><textarea name="message" rows="2" cols="50" required></textarea></td>
        </tr>
        <tr>
            <td><label for='userfile'>Ajouter une pièce jointe<span></span></label></td>
            <td><input type="file" name="userfile" id="userfile" required/></td>
        </tr>
        <tr>
            <td></td>
            <td><input name="sendmail" type="submit" value="Envoyer"></td>
        </tr>
    </table>
</form>
Encore merci à tout ceux qui m'ont aider !

Re: Phpmailer pour mail avec pièce jointe

par Saian » 18 juil. 2019, 12:13

Un petit if (isset($msg)) echo $msg; juste au dessus de ton formulaire ? (entre le code php et le formulaire)

Re: Phpmailer pour mail avec pièce jointe

par la_belette » 18 juil. 2019, 12:05

J'ai un peu avancé et le résultat est (presque) parfait !
<?php
use PHPMailer\PHPMailer\PHPMailer;
if (isset($_POST['sendmail'])) {

    if (isset($_FILES["userfile"]) && $_FILES['userfile']['name'] != "") {
        $nom_fichier = $_FILES['userfile']['name'];
        $source = $_FILES['userfile']['tmp_name'];
        $type_fichier = $_FILES['userfile']['type'];
        $taille_fichier = $_FILES['userfile']['size'];

        if ($nom_fichier != ".htaccess") { //Vérifie que ce n'est pas un .htaccess
            if ($type_fichier == "image/jpeg"
                || $type_fichier == "image/pjpeg"
                || $type_fichier == "application/pdf") { //Soit un jpeg soit un pdf

                if (array_key_exists('userfile', $_FILES)) {
                    $uploadfile = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['userfile']['name']));
                    if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
                        // Upload handled successfully
                        // Now create a message
                        $msg = '';
                        require '../phpmailer/src/PHPMailer.php';
                        $mail = new PHPMailer;
                        $mail->setFrom($_POST['email'], $_POST['name']);
                        $mail->addAddress('[email protected]');
                        $mail->Subject = $_POST['offre'];
                        $mail->Body = $_POST['message'];
                        // Attach the uploaded file
                        $mail->addAttachment($uploadfile,$nom_fichier);
                        if (!$mail->send()) {
                            $msg .= "Mailer Error: " . $mail->ErrorInfo;
                        } else {
                            $msg .= "Message sent!";
                        }
                    } else {
                        $msg .= 'Failed to move file to ' . $uploadfile;
                    }
                }
            }
        }
    }
}
?>
<form enctype="multipart/form-data" action="testmail.php" method="post">
    <table>
        <tr>
            <td><label for="nom">Votre nom<div style="color:red;display:inline;">*</div> :</label></td>
            <td><input type="text" name="name" required/></td>
        </tr>
        <tr>
            <td><label for="email">Votre E-mail<div style="color:red;display:inline;">*</div> :</label></td>
            <td><input type="email" name="email" required/></td>
        </tr>
        <tr>
            <td>Votre offre<div style="color:red;display:inline;">*</div> :</td>
            <td><input type="text" name="offre" required/></td>
        </tr>
        <tr>
            <td><label for="message">Vos motivations<div style="color:red;display:inline;">*</div> :</label></td>
            <td><textarea name="message" rows="2" cols="50" required></textarea></td>
        </tr>
        <tr>
            <td><label for='userfile'>Ajouter une pièce jointe<span></span></label></td>
            <td><input type="file" name="userfile" id="userfile"></td>
        </tr>
        <tr>
            <td></td>
            <td><input name="sendmail" type="submit" value="Envoyer"></td>
        </tr>
    </table>
</form>
Alors, j'ai un peu regardé à droite à et à gauche comment les gens ont fait et j'ai pu ajouter les conditions pour le mail qui fonctionnent. Je n'arrive pas à envoyer autre chose que des pdf, et jpeg. Donc ce soucis est résolu.

Désormais, en ajoutant la variable $nom_fichier qui correspond à $_FILES['userfile']['name'] le nom du fichier s'affiche avec l'extension dans le mail, pas de risque d'ouvrir un .exe ou pire, donc.

Mon dernier soucis semble presque bête, pour le coup... Je n'arrive pas à faire apparaître "Message sent" ou "Mailer error". L'utilisateur ne saura donc pas ce qui arrive à ses informations !

Re: Phpmailer pour mail avec pièce jointe

par Saian » 18 juil. 2019, 11:10

Salut, le nom est bien le résultat du tempnam oui. Tu peux trouver le nom original du fichier dans $_FILES.
https://www.php.net/manual/fr/reserved. ... .files.php

Le array_key_exists vérifie juste que la clé userfile existe bien dans $_FILES. Si tu veux vérifier l'extension du fichier il faut que tu rajoutes le code pour et il y a là bien des manières de le faire. Tu pourrais par exemple utiliser la fonction pathinfo.
https://www.php.net/manual/fr/function.pathinfo.php

Re: Phpmailer pour mail avec pièce jointe

par la_belette » 18 juil. 2019, 09:04

Après avoir changé mon form en ajoutant enctype="multipart/form-data" ce dernier ne semblait pas avoir changé grand chose.

MAIS j'ai bien reçu un mail avec une pièce jointe ! Nouveau problème, ce dernier s'affiche comme "My uploaded file". Lorsque je le télécharge, il son nom est donc "Myuploadedfile - vrainomdufichier.extension". Est-il possible de corriger cela ?
De plus, j'aurai aimé pouvoir accepté uniquement les fichiers pdf et jpeg/jpg/png.

Pour finir ce que je trouve étrange c'est que vu que le mail part, pourquoi n'ai-je pas eu le "message sent" ?

EDIT :

Après avoir regardé, j'ai trouvé pourquoi le nom du fichier était "My uploaded file". J'ai donc essayé en changeant la ligne
$mail->addAttachment($uploadfile);
mais cette fois le fichier à un nom "crypté". Je suppose que c'est le résultat de
$uploadfile = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['userfile']['name']));


Enfin, pour modifier le fait de rejeter les fichiers hors pdf, JPG, JPEG,PNG, je suppose que je dois rajouter une condition dans
if (array_key_exists('userfile', $_FILES))

Re: Phpmailer pour mail avec pièce jointe

par or 1 » 17 juil. 2019, 17:22

avec <form enctype="multipart/form-data" action="testmail.php" method="post"> ?

Re: Phpmailer pour mail avec pièce jointe

par la_belette » 17 juil. 2019, 16:58

Plus tôt,il rentrait dans la première boucle et m'affichait l'erreur de
$msg .= 'Failed to move file to ' . $uploadfile;
Désormais, en remplissant le formulaire je n'ai qu'un rafraîchissement de la page, sans mail qui part, sans message d'erreur. Je suppose donc qu'il ne rentre plus dans les boucles.

Je viens d'essayer en retirant
if (isset($_POST['sendmail'])) {
mais rien ne change, le problème n'est donc pas là.

Re: Phpmailer pour mail avec pièce jointe

par @rthur » 17 juil. 2019, 16:53

Bonjour,

Quel est le problème exactement ?

Phpmailer pour mail avec pièce jointe

par la_belette » 17 juil. 2019, 16:50

Bonjour/Bonsoir,

Après avoir essayer en vain de m'en passer pour envoyer des mails avec pièces jointe, j'ai décidé d'utiliser phpmailer pour un mail post formulaire. Voici le code :
<?php
use PHPMailer\PHPMailer\PHPMailer;
if (isset($_POST['sendmail'])) {
    if (array_key_exists('userfile', $_FILES)) {
        $uploadfile = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['userfile']['name']));
        if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
            // Upload handled successfully
            // Now create a message
            require '../phpmailer/src/PHPMailer.php';
            $mail = new PHPMailer;
            $mail->setFrom($_POST['email'], $_POST['name']);
            $mail->addAddress('[email protected]');
            $mail->Subject = $_POST['offre'];
            $mail->Body = $_POST['message'];
            // Attach the uploaded file
            $mail->addAttachment($uploadfile, 'My uploaded file');
            if (!$mail->send()) {
                $msg .= "Mailer Error: " . $mail->ErrorInfo;
            } else {
                $msg .= "Message sent!";
            }
        } else {
            $msg .= 'Failed to move file to ' . $uploadfile;
        }
    }
}
?>
<form action="testmail.php" method="post">
    <table>
        <tr>
            <td><label for="nom">Votre nom<div style="color:red;display:inline;">*</div> :</label></td>
            <td><input type="text" name="name" required/></td>
        </tr>
        <tr>
            <td><label for="email">Votre E-mail<div style="color:red;display:inline;">*</div> :</label></td>
            <td><input type="email" name="email" required/></td>
        </tr>
        <tr>
            <td>Votre offre<div style="color:red;display:inline;">*</div> :</td>
            <td><input type="text" name="offre" required/></td>
        </tr>
        <tr>
            <td><label for="message">Vos motivations<div style="color:red;display:inline;">*</div> :</label></td>
            <td><textarea name="message" rows="2" cols="50" required></textarea></td>
        </tr>
        <tr>
            <td><label for='userfile'>Ajouter une pièce jointe<span></span></label></td>
            <td><input type="file" name="userfile" id="userfile"></td>
        </tr>
        <tr>
            <td></td>
            <td><input name="sendmail" type="submit" value="Envoyer"></td>
        </tr>
    </table>
</form>
(J'ai pris le code PHP directement dans les exemples de phpmailer, au passage. je n'ai fais que changer quelques lignes pour que ça colle avec mon formulaire ainsi que la ligne "require" qu'il pointait vers un dossier "vendor" que je n'ai pas.)

Malheureusement, je n'ai le droit qu'à un rafraîchissement de page..! Ça fait quelques temps que je suis sur ce soucis pourtant avec mail sans pièce jointe pas de soucis.. !

Si quelqu'un arrive à voir d'où peut venir le soucis et me le dire, ça m'aiderait beaucoup. En attendant, je cherche de mon côté !