La fonction de messagerie PHP ne termine pas l'envoi des e-mails


477
<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];
    $from = 'From: yoursite.com';
    $to = 'contact@yoursite.com';
    $subject = 'Customer Inquiry';
    $body = "From: $name\n E-Mail: $email\n Message:\n $message";

    if ($_POST['submit']) {
        if (mail ($to, $subject, $body, $from)) {
            echo '<p>Your message has been sent!</p>';
        } else {
            echo '<p>Something went wrong, go back and try again!</p>';
        }
    }
?>

J'ai essayé de créer un simple formulaire de messagerie. Le formulaire lui-même est sur ma index.htmlpage, mais il se soumet à une page séparée "merci pour votre soumission" thankyou.php, où le code PHP ci-dessus est intégré. Le code se soumet parfaitement, mais n'envoie jamais d'email. Comment puis-je réparer cela?


2
est votre programme sur un ordinateur local ou un hôte en direct
Tamil Selvan C

6
1. êtes-vous sûr qu'il n'entre pas dans votre spam? 2. avez-vous configuré sendmail sur votre box?
Steven Moseley

son sur un hôte en direct, il ne va pas dans mon spam .. je ne sais pas ce que vous entendez par avoir sendmail configuré sur ma boîte, donc je suppose que non?
user3818620

essayez d'envoyer sans$from
Artem Ilchenko

Réponses:


512

Bien que certaines parties de cette réponse s'appliquent uniquement à l'utilisation de la mail()fonction elle-même, bon nombre de ces étapes de dépannage peuvent être appliquées à n'importe quel système de messagerie PHP.

Il existe diverses raisons pour lesquelles votre script ne semble pas envoyer d’e-mails. Il est difficile de diagnostiquer ces choses sauf en cas d'erreur de syntaxe évidente. Sans celui-ci, vous devez parcourir la liste de contrôle ci-dessous pour trouver les pièges potentiels que vous pourriez rencontrer.

Assurez-vous que le rapport d'erreurs est activé et configuré pour signaler toutes les erreurs

Le rapport d'erreurs est essentiel pour éliminer les bogues dans votre code et les erreurs générales rencontrées par PHP. Le rapport d'erreurs doit être activé pour recevoir ces erreurs. Le fait de placer le code suivant en haut de vos fichiers PHP (ou dans un fichier de configuration principal) activera le rapport d'erreurs.

error_reporting(-1);
ini_set('display_errors', 'On');
set_error_handler("var_dump");

Voir Comment puis-je obtenir des messages d'erreur utiles en PHP? - cette réponse pour plus de détails à ce sujet.

Assurez-vous que la mail()fonction est appelée

Cela peut sembler idiot, mais une erreur courante consiste à oublier de placer réellement la mail()fonction dans votre code. Assurez-vous qu'il est là et non commenté.

Assurez-vous que la mail()fonction est appelée correctement

bool mail (string $ to, string $ subject, string $ message [, string $ additional_headers [, string $ additional_parameters]])

La fonction de messagerie prend trois paramètres obligatoires et éventuellement un quatrième et un cinquième. Si votre appel à mail()n'a pas au moins trois paramètres, il échouera.

Si votre appel à mail()n'a pas les bons paramètres dans le bon ordre, il échouera également.

Vérifiez les journaux de messagerie du serveur

Votre serveur Web doit consigner toutes les tentatives d'envoi d'e-mails via celui-ci. L'emplacement de ces journaux variera (vous devrez peut-être demander à votre administrateur de serveur où ils se trouvent), mais ils peuvent généralement être trouvés dans le répertoire racine d'un utilisateur sous logs. À l'intérieur, des messages d'erreur signalés par le serveur, le cas échéant, liés à vos tentatives d'envoi d'e-mails.

Vérifier l'échec de la connexion au port

Le bloc de ports est un problème très courant auquel la plupart des développeurs sont confrontés lors de l'intégration de leur code pour envoyer des e-mails à l'aide de SMTP. Et cela peut être facilement retracé au niveau des serveurs maillogs (l'emplacement du serveur du journal de messagerie peut varier d'un serveur à l'autre, comme expliqué ci-dessus). Si vous êtes sur un serveur d'hébergement partagé, les ports 25 et 587 restent bloqués par défaut. Ce blocage a été fait exprès par votre hébergeur. Cela est vrai même pour certains des serveurs dédiés. Lorsque ces ports sont bloqués, essayez de vous connecter en utilisant le port 2525. Si vous trouvez que ce port est également bloqué, alors la seule solution est de contacter votre hébergeur pour débloquer ces ports.

La plupart des hébergeurs bloquent ces ports de messagerie pour protéger leur réseau contre l'envoi de spam.

Utilisez les ports 25 ou 587 pour les connexions standard / TLS et le port 465 pour les connexions SSL. Pour la plupart des utilisateurs, il est suggéré d'utiliser le port 587 pour éviter les limites de débit fixées par certains hébergeurs.

N'utilisez pas l'opérateur de suppression d'erreur

Lorsque l' opérateur de suppression d'erreur @ est ajouté à une expression en PHP, tous les messages d'erreur qui pourraient être générés par cette expression seront ignorés. Il y a des circonstances où l'utilisation de cet opérateur est nécessaire mais l'envoi de courrier n'en fait pas partie.

Si votre code contient, @mail(...)vous pouvez masquer des messages d'erreur importants qui vous aideront à déboguer cela. Retirez le @et voyez si des erreurs sont signalées.

Il n'est conseillé que lorsque vous vérifiezerror_get_last() immédiatement après pour les défaillances concrètes.

Vérifiez la mail()valeur de retour

La mail()fonction:

Retourne TRUEsi le courrier a été accepté avec succès pour la livraison, FALSEsinon. Il est important de noter que le simple fait que le courrier ait été accepté pour la livraison ne signifie PAS que le courrier atteindra réellement la destination prévue.

Ceci est important à noter car:

  • Si vous recevez une FALSEvaleur de retour, vous savez que l'erreur réside dans le fait que votre serveur accepte votre courrier. Ce n'est probablement pas un problème de codage mais un problème de configuration du serveur. Vous devez parler à votre administrateur système pour savoir pourquoi cela se produit.
  • Si vous recevez une TRUEvaleur de retour, cela ne signifie pas que votre e-mail sera définitivement envoyé. Cela signifie simplement que l'e-mail a été envoyé avec succès à son gestionnaire respectif sur le serveur par PHP. Il y a encore plus de points de défaillance hors du contrôle de PHP qui peuvent empêcher l'envoi de l'e-mail.

Cela FALSEvous aidera donc à vous orienter dans la bonne direction, ce TRUEqui ne signifie pas nécessairement que votre e-mail a bien été envoyé. Ceci est important à noter!

Assurez-vous que votre hébergeur vous autorise à envoyer des e-mails et ne limite pas l'envoi de courrier

De nombreux hébergeurs partagés, en particulier les hébergeurs gratuits, n'autorisent pas l'envoi d'e-mails depuis leurs serveurs ou limitent le montant pouvant être envoyé au cours d'une période donnée. Cela est dû à leurs efforts pour empêcher les spammeurs de profiter de leurs services moins chers.

Si vous pensez que votre hôte a des limites d'e-mailing ou bloque l'envoi d'e-mails, consultez leur FAQ pour voir s'il répertorie ces limitations. Sinon, vous devrez peut-être contacter leur support pour vérifier s'il existe des restrictions concernant l'envoi d'e-mails.

Vérifiez les dossiers de spam; empêcher les e-mails d'être marqués comme spam

Souvent, pour diverses raisons, les e-mails envoyés via PHP (et d'autres langages de programmation côté serveur) se retrouvent dans le dossier spam d'un destinataire. Vérifiez toujours là avant de dépanner votre code.

Pour éviter que le courrier envoyé via PHP ne soit envoyé dans le dossier de spam d'un destinataire, vous pouvez effectuer différentes actions, à la fois dans votre code PHP et autrement, pour minimiser les chances que vos e-mails soient marqués comme spam. Les bons conseils de Michiel de Mare incluent:

  • Utilisez des méthodes d'authentification des e-mails, telles que SPF et DKIM pour prouver que vos e-mails et votre nom de domaine vont de pair et pour empêcher l'usurpation de votre nom de domaine. Le site Web SPF comprend un assistant pour générer les informations DNS pour votre site.
  • Vérifiez votre DNS inversé pour vous assurer que l'adresse IP de votre serveur de messagerie pointe vers le nom de domaine que vous utilisez pour envoyer du courrier.
  • Assurez-vous que l'adresse IP que vous utilisez n'est pas sur une liste noire
  • Assurez-vous que l'adresse de réponse est une adresse existante valide.
  • Utilisez le nom complet et réel du destinataire dans le champ À, pas seulement l'adresse e-mail (par exemple "John Smith" <john@blacksmiths-international.com>).
  • Surveillez vos comptes d'abus, tels que abuse@votredomaine.com et postmaster@votredomaine.com. Cela signifie - assurez-vous que ces comptes existent, lisez ce qui leur est envoyé et donnez suite aux plaintes.
  • Enfin, le rendre vraiment facile de se désabonner. Sinon, vos utilisateurs se désinscrireont en appuyant sur le bouton spam , ce qui affectera votre réputation.

Voir Comment vous assurer que les e-mails que vous envoyez par programmation ne sont pas automatiquement marqués comme spam? pour en savoir plus sur ce sujet.

Assurez-vous que tous les en-têtes de courrier sont fournis

Certains logiciels de spam rejetteront le courrier s'il manque des en-têtes courants tels que "De" et "Répondre à":

$headers = array("From: from@example.com",
    "Reply-To: replyto@example.com",
    "X-Mailer: PHP/" . PHP_VERSION
);
$headers = implode("\r\n", $headers);
mail($to, $subject, $message, $headers);

Assurez-vous que les en-têtes de courrier ne contiennent aucune erreur de syntaxe

Les en-têtes non valides sont tout aussi mauvais que l'absence d'en-têtes. Un caractère incorrect pourrait suffire à faire dérailler votre e-mail. Revérifiez pour vous assurer que votre syntaxe est correcte car PHP ne détectera pas ces erreurs pour vous.

$headers = array("From from@example.com", // missing colon
    "Reply To: replyto@example.com",      // missing hyphen
    "X-Mailer: "PHP"/" . PHP_VERSION      // bad quotes
);

N'utilisez pas de faux From:expéditeur

Bien que l'e-mail doive avoir un expéditeur From:, vous ne pouvez pas utiliser n'importe quelle valeur. En particulier, les adresses d'expéditeur envoyées par l'utilisateur sont un moyen infaillible de bloquer les e-mails:

$headers = array("From: $_POST[contactform_sender_email]"); // No!

Raison: votre serveur Web ou d'envoi de messagerie n'est pas inscrit sur la liste blanche SPF / DKIM pour prétendre être responsable des adresses @hotmail ou @gmail. Il peut même supprimer silencieusement des messages avec des From:domaines d'expéditeur pour lesquels il n'est pas configuré.

Assurez-vous que la valeur du destinataire est correcte

Parfois, le problème est aussi simple que d'avoir une valeur incorrecte pour le destinataire de l'e-mail. Cela peut être dû à l'utilisation d'une variable incorrecte.

$to = 'user@example.com';
// other variables ....
mail($recipient, $subject, $message, $headers); // $recipient should be $to

Une autre façon de tester cela consiste à coder en dur la valeur du destinataire dans l' mail()appel de fonction:

mail('user@example.com', $subject, $message, $headers); 

Cela peut s'appliquer à tous les mail()paramètres.

Envoyer vers plusieurs comptes

Pour éliminer les problèmes de compte de messagerie, envoyez votre e-mail à plusieurs comptes de messagerie chez différents fournisseurs de messagerie . Si vos e-mails ne parviennent pas au compte Gmail d'un utilisateur, envoyez les mêmes e-mails à un compte Yahoo, un compte Hotmail et un compte POP3 normal (comme votre compte de messagerie fourni par le FAI).

Si les e-mails arrivent à tout ou partie des autres comptes de messagerie, vous savez que votre code envoie des e-mails, mais il est probable que le fournisseur de compte de messagerie les bloque pour une raison quelconque. Si l'e-mail n'arrive sur aucun compte de messagerie, le problème est probablement lié à votre code.

Assurez-vous que le code correspond à la méthode du formulaire

Si vous avez défini votre méthode de formulaire sur POST, assurez-vous que vous utilisez $_POSTpour rechercher vos valeurs de formulaire. Si vous l'avez défini GETou ne l' avez pas défini du tout, assurez-vous que vous utilisez $_GETpour rechercher les valeurs de votre formulaire.

Assurez-vous que la actionvaleur de votre formulaire pointe vers l'emplacement correct

Assurez-vous que votre actionattribut de formulaire contient une valeur qui pointe vers votre code de diffusion PHP.

<form action="send_email.php" method="POST">

Assurez-vous que l'hôte Web prend en charge l'envoi d'e-mails

Certains fournisseurs d'hébergement Web n'autorisent pas ou n'autorisent pas l'envoi d'e-mails via leurs serveurs. Les raisons peuvent varier, mais si elles ont désactivé l'envoi de courrier, vous devrez utiliser une méthode alternative qui utilise un tiers pour envoyer ces e-mails pour vous.

Un e-mail à leur support technique (après un voyage vers leur support en ligne ou FAQ) devrait clarifier si les capacités de messagerie sont disponibles sur votre serveur.

Assurez-vous que le localhostserveur de messagerie est configuré

Si vous développez sur votre poste de travail local à l'aide de WAMP, MAMP ou XAMPP, un serveur de messagerie n'est probablement pas installé sur votre poste de travail. Sans celui-ci, PHP ne peut pas envoyer de courrier par défaut.

Vous pouvez surmonter cela en installant un serveur de messagerie de base. Pour Windows, vous pouvez utiliser le Mercury Mail gratuit .

Vous pouvez également utiliser SMTP pour envoyer vos e-mails. Voir cette excellente réponse de Vikas Dwivedi pour apprendre comment faire cela.

Activer la personnalisation de PHP mail.log

En plus du fichier journal de votre MTA et PHP, vous pouvez activer la journalisation pour la mail()fonction en particulier. Il n'enregistre pas l'interaction SMTP complète, mais au moins les paramètres d'appel de fonction et le script d'appel.

ini_set("mail.log", "/tmp/mail.log");
ini_set("mail.add_x_header", TRUE);

Voir http://php.net/manual/en/mail.configuration.php pour plus de détails. (Il est préférable d'activer ces options dans le php.iniou .user.iniou .htaccesspeut - être.)

Vérifiez auprès d'un service de test de courrier

Il existe différents services de livraison et de vérification du spam que vous pouvez utiliser pour tester la configuration de votre MTA / serveur Web. En règle générale, vous envoyez une sonde de messagerie à: leur adresse, puis obtenez un rapport de livraison et des échecs ou analyses plus concrets plus tard:

Utilisez un autre expéditeur

La mail()fonction intégrée de PHP est pratique et fait souvent le travail, mais elle a ses défauts . Heureusement, il existe des alternatives qui offrent plus de puissance et de flexibilité, notamment la gestion de la plupart des problèmes décrits ci-dessus:

Le tout pouvant être combiné avec un serveur / fournisseur de services SMTP professionnel. (Parce que les plans d'hébergement Web partagés typiques 08/15 sont aléatoires en ce qui concerne la configuration / configurabilité des e-mails.)


11
Bien écrit, John. Je voudrais juste ajouter une chose: vérifier les journaux du serveur de messagerie du serveur de messagerie d'envoi (qu'il soit hébergé localement ou à distance), si possible, peut souvent faire la lumière sur la cause du problème. Ces journaux doivent indiquer 1) si le message a été reçu du script PHP par le serveur de messagerie expéditeur et, le cas échéant, 2) si le MX destinataire a accepté ou non la livraison du serveur de messagerie expéditeur.
mti2935

@ mti2935 C'est tellement utile que je suis surpris d'avoir raté ça. Je ne manquerai pas de l'ajouter sous peu. :)
John Conde

1
je commencerais par ne pas utiliser mail(), il fait un si mauvais travail et est plus difficile à déboguer que toute autre bibliothèque de messagerie

1
le même site Web sur 000webhost envoie des courriels avec succès et rapidement sur le domaine netai.net mais sur site88.net j'ai le même site Web que j'obtiens dans la console que le message envoie avec succès mais je ne reçois aucun message. Également dans le domaine comuf.com, je reçois une erreur (le même site Web sur le même hôte ne fonctionne que sur le domaine netai.net, net16.net fonctionne également)
Nicolas Papaconstantinou

1
ma question ( stackoverflow.com/questions/44866673/… ) a été marquée comme une copie de celle-ci, mais je ne parviens toujours pas à le comprendre. Aucune suggestion?
Zachary Elkins

37

Ajoutez un en-tête de mail dans la fonction mail:

$header = "From: noreply@example.com\r\n";
$header.= "MIME-Version: 1.0\r\n";
$header.= "Content-Type: text/html; charset=ISO-8859-1\r\n";
$header.= "X-Priority: 1\r\n";

$status = mail($to, $subject, $message, $header);

if($status)
{
    echo '<p>Your mail has been sent!</p>';
} else {
    echo '<p>Something went wrong. Please try again!</p>';
}

25
  1. Essayez toujours d'envoyer des en-têtes dans la fonction de messagerie.
  2. Si vous envoyez du courrier via localhost, définissez les paramètres SMTP pour l'envoi du courrier.
  3. Si vous envoyez du courrier via un serveur, vérifiez que la fonction d'envoi de courrier électronique est activée sur votre serveur.

20

Si vous utilisez une configuration SMTP pour envoyer votre courrier électronique, essayez plutôt d' utiliser PHPMailer . Vous pouvez télécharger la bibliothèque à partir de https://github.com/PHPMailer/PHPMailer .

J'ai créé mon email en envoyant de cette façon:

function send_mail($email, $recipient_name, $message='')
{
    require("phpmailer/class.phpmailer.php");

    $mail = new PHPMailer();

    $mail->CharSet = "utf-8";
    $mail->IsSMTP();                                      // Set mailer to use SMTP
    $mail->Host = "mail.example.com";  // Specify main and backup server
    $mail->SMTPAuth = true;     // Turn on SMTP authentication
    $mail->Username = "myusername";  // SMTP username
    $mail->Password = "p@ssw0rd"; // SMTP password

    $mail->From = "me@walalang.com";
    $mail->FromName = "System-Ad";
    $mail->AddAddress($email, $recipient_name);

    $mail->WordWrap = 50;                                 // Set word wrap to 50 characters
    $mail->IsHTML(true);                                  // Set email format to HTML (true) or plain text (false)

    $mail->Subject = "This is a Sampleenter code here Email";
    $mail->Body    = $message;
    $mail->AltBody = "This is the body in plain text for non-HTML mail clients";
    $mail->AddEmbeddedImage('images/logo.png', 'logo', 'logo.png');
    $mail->addAttachment('files/file.xlsx');

    if(!$mail->Send())
    {
       echo "Message could not be sent. <p>";
       echo "Mailer Error: " . $mail->ErrorInfo;
       exit;
    }

    echo "Message has been sent";
}

2
J'ai également dû utiliser: require ("phpmailer / class.smtp.php");
Doug

15

Ajoutez simplement des en-têtes avant d'envoyer du courrier:

<?php 
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com'; 
$to = 'contact@yoursite.com'; 
$subject = 'Customer Inquiry';
$body = "From: $name\n E-Mail: $email\n Message:\n $message";

$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html\r\n";
$headers .= 'From: from@example.com' . "\r\n" .
'Reply-To: reply@example.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();

mail($to, $subject, $message, $headers);

Et encore une chose. La mail()fonction ne fonctionne pas dans localhost. Téléchargez votre code sur un serveur et essayez.


1
En fait, le formulaire a été soumis - ma question serait maintenant ... comment puis-je montrer le courrier électronique tapé de l'utilisateur, maintenant que je l'ai remplacé par l'en-tête ...
user3818620

cela empêchera-t-il le courrier du dossier spam. J'ai vu si nous envoyons plus de 10 e-mails en utilisant cette méthode que vous avez utilisée dans votre code gmail envoyer ce courrier à du spam.
jewelhuq

L'OP a cette ligne: $from = 'From: yoursite.com'; qui ne ressemble pas à une adresse e-mail valide complète, il n'y a pas de partie locale. Vous avez remplacé l'en-tête De et en avez ajouté d'autres. Ou plutôt ce qui $fromprécède est redondant dans votre exemple. Et être mal formé était probablement le problème d'origine des PO.
Progrock

13

Cela a fonctionné pour moi sur 000webhost en procédant comme suit:

$headers  = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type: text/html; charset=iso-8859-1" . "\r\n";
$headers .= "From: ". $from. "\r\n";
$headers .= "Reply-To: ". $from. "\r\n";
$headers .= "X-Mailer: PHP/" . phpversion();
$headers .= "X-Priority: 1" . "\r\n";

Saisissez directement l'adresse e-mail lors de l'envoi de l'e-mail:

mail('email@gmail.com', $subject, $message, $headers)

Utilisez ''et non "".

Ce code fonctionne, mais l'e-mail a été reçu avec une demi-heure de retard.


10

Généralement, la mail()fonction est désactivée dans l'hébergement partagé. Une meilleure option consiste à utiliser SMTP. La meilleure option serait Gmail ou SendGrid.


SMTPconfig.php

<?php 
    $SmtpServer="smtp.*.*";
    $SmtpPort="2525"; //default
    $SmtpUser="***";
    $SmtpPass="***";
?>

SMTPmail.php

<?php
class SMTPClient
{

    function SMTPClient ($SmtpServer, $SmtpPort, $SmtpUser, $SmtpPass, $from, $to, $subject, $body)
    {

        $this->SmtpServer = $SmtpServer;
        $this->SmtpUser = base64_encode ($SmtpUser);
        $this->SmtpPass = base64_encode ($SmtpPass);
        $this->from = $from;
        $this->to = $to;
        $this->subject = $subject;
        $this->body = $body;

        if ($SmtpPort == "") 
        {
            $this->PortSMTP = 25;
        }
        else
        {
            $this->PortSMTP = $SmtpPort;
        }
    }

    function SendMail ()
    {
        $newLine = "\r\n";
        $headers = "MIME-Version: 1.0" . $newLine;  
        $headers .= "Content-type: text/html; charset=iso-8859-1" . $newLine;  

        if ($SMTPIN = fsockopen ($this->SmtpServer, $this->PortSMTP)) 
        {
            fputs ($SMTPIN, "EHLO ".$HTTP_HOST."\r\n"); 
            $talk["hello"] = fgets ( $SMTPIN, 1024 ); 
            fputs($SMTPIN, "auth login\r\n");
            $talk["res"]=fgets($SMTPIN,1024);
            fputs($SMTPIN, $this->SmtpUser."\r\n");
            $talk["user"]=fgets($SMTPIN,1024);
            fputs($SMTPIN, $this->SmtpPass."\r\n");
            $talk["pass"]=fgets($SMTPIN,256);
            fputs ($SMTPIN, "MAIL FROM: <".$this->from.">\r\n"); 
            $talk["From"] = fgets ( $SMTPIN, 1024 ); 
            fputs ($SMTPIN, "RCPT TO: <".$this->to.">\r\n"); 
            $talk["To"] = fgets ($SMTPIN, 1024); 
            fputs($SMTPIN, "DATA\r\n");
            $talk["data"]=fgets( $SMTPIN,1024 );
            fputs($SMTPIN, "To: <".$this->to.">\r\nFrom: <".$this->from.">\r\n".$headers."\n\nSubject:".$this->subject."\r\n\r\n\r\n".$this->body."\r\n.\r\n");
            $talk["send"]=fgets($SMTPIN,256);
            //CLOSE CONNECTION AND EXIT ... 
            fputs ($SMTPIN, "QUIT\r\n"); 
            fclose($SMTPIN); 
            // 
        } 
        return $talk;
    } 
}
?>

contact_email.php

<?php 
include('SMTPconfig.php');
include('SMTPmail.php');
if($_SERVER["REQUEST_METHOD"] == "POST")
{
    $to = "";
    $from = $_POST['email'];
    $subject = "Enquiry";
    $body = $_POST['name'].'</br>'.$_POST['companyName'].'</br>'.$_POST['tel'].'</br>'.'<hr />'.$_POST['message'];
    $SMTPMail = new SMTPClient ($SmtpServer, $SmtpPort, $SmtpUser, $SmtpPass, $from, $to, $subject, $body);
    $SMTPChat = $SMTPMail->SendMail();
}
?>

Est-ce une bonne idée de sauvegarder l'utilisateur smtp et le mot de passe en clair sur le serveur?
Juri

@Juri probablement pas ... mon dieu, je ne peux pas comprendre comment faire fonctionner la fonction de messagerie

9

Si vous utilisez uniquement la mail()fonction, vous devez compléter le fichier de configuration.

Vous devez ouvrir l'extension de messagerie et définir le SMTP smtp_portet ainsi de suite, et le plus important, votre nom d'utilisateur et votre mot de passe. Sans cela, le courrier ne peut pas être envoyé. Vous pouvez également utiliser la PHPMailclasse pour envoyer.


9

Essayez ces deux choses séparément et ensemble:

  1. retirer le if($_POST['submit']){}
  2. enlever $from(juste mon instinct)

8

Je pense que cela devrait faire l'affaire. Je viens d'ajouter une if(issetet une concaténation aux variables dans le corps pour séparer PHP du HTML.

<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];
    $from = 'From: yoursite.com'; 
    $to = 'contact@yoursite.com'; 
    $subject = 'Customer Inquiry';
    $body = "From:" .$name."\r\n E-Mail:" .$email."\r\n Message:\r\n" .$message;

if (isset($_POST['submit'])) 
{
    if (mail ($to, $subject, $body, $from)) 
    { 
        echo '<p>Your message has been sent!</p>';
    } 
    else 
    { 
        echo '<p>Something went wrong, go back and try again!</p>'; 
    }
}

?>

8

Pour tous ceux qui trouvent cela à l'avenir, je ne recommanderais pas d'utiliser mail. Il y a quelques réponses qui touchent à cela, mais pas le pourquoi .

La mailfonction de PHP n'est pas seulement opaque, elle dépend entièrement du MTA que vous utilisez (ie Sendmail ) pour faire le travail. mailsera seulement vous dire si le MTA n'a pas réussi à l' accepter (c. -à- Sendmail est en baisse lorsque vous avez essayé d'envoyer). Il ne peut pas vous dire si le courrier a réussi, car il l'a remis. En tant que tel (comme la réponse de John Conde détails de la ), vous pouvez désormais jouer avec les journaux du MTA et espérer qu'il vous en dira assez sur l'échec de la correction. Si vous êtes sur un hôte partagé ou n'avez pas accès aux journaux MTA, vous n'avez pas de chance. Malheureusement, la valeur par défaut pour la plupart des installations vanilla pour Linux le gère de cette façon.

Une bibliothèque de messagerie ( PHPMailer , Zend Framework 2+, etc.) fait quelque chose de très différent de mail. Ils ouvrent un socket directement sur le serveur de messagerie destinataire, puis envoient les commandes de messagerie SMTP directement sur ce socket. En d'autres termes, la classe agit comme son propre MTA (notez que vous pouvez dire aux bibliothèques à utiliser mailpour envoyer le courrier, mais je vous recommande fortement de ne pas le faire).

Cela signifie que vous pouvez alors voir directement les réponses du serveur de réception (dans PHPMailer, par exemple, vous pouvez activer la sortie de débogage ). Plus besoin de deviner si un mail n'a pas pu être envoyé ou pourquoi.

Si vous utilisez SMTP (c'est-à-dire que vous appelez isSMTP()), vous pouvez obtenir une transcription détaillée de la conversation SMTP en utilisant la SMTPDebugpropriété.

Définissez cette option en incluant une ligne comme celle-ci dans votre script:

$mail->SMTPDebug = 2;

Vous bénéficiez également d'une meilleure interface. Avec mailvous devez configurer tous vos en-têtes, pièces jointes, etc. Avec une bibliothèque, vous avez une fonction dédiée pour le faire. Cela signifie également que la fonction effectue toutes les parties délicates (comme les en-têtes).


6
$name = $_POST['name'];
$email = $_POST['email'];
$reciver = '/* Reciver Email address */';
if (filter_var($reciver, FILTER_VALIDATE_EMAIL)) {
    $subject = $name;
    // To send HTML mail, the Content-type header must be set.
    $headers = 'MIME-Version: 1.0' . "\r\n";
    $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
    $headers .= 'From:' . $email. "\r\n"; // Sender's Email
    //$headers .= 'Cc:' . $email. "\r\n"; // Carbon copy to Sender
    $template = '<div style="padding:50px; color:white;">Hello ,<br/>'
        . '<br/><br/>'
        . 'Name:' .$name.'<br/>'
        . 'Email:' .$email.'<br/>'
        . '<br/>'
        . '</div>';
    $sendmessage = "<div style=\"background-color:#7E7E7E; color:white;\">" . $template . "</div>";
    // Message lines should not exceed 70 characters (PHP rule), so wrap it.
    $sendmessage = wordwrap($sendmessage, 70);
    // Send mail by PHP Mail Function.
    mail($reciver, $subject, $sendmessage, $headers);
    echo "Your Query has been received, We will contact you soon.";
} else {
    echo "<span>* invalid email *</span>";
}

6

Vous pouvez utiliser l'e-mail de configuration par CodeIgniter . Par exemple, en utilisant SMTP (manière simple):

$config = Array(
        'protocol' => 'smtp',
        'smtp_host' => 'mail.domain.com', // Your SMTP host
        'smtp_port' => 26, // Default port for SMTP
        'smtp_user' => 'name@domain.com',
        'smtp_pass' => 'password',
        'mailtype' => 'html',
        'charset' => 'iso-8859-1',
        'wordwrap' => TRUE
);
$message = 'Your msg';
$this->load->library('email', $config);
$this->email->from('name@domain.com', 'Title');
$this->email->to('emaildestination@domain.com');
$this->email->subject('Header');
$this->email->message($message);

if($this->email->send()) 
{
   // Conditional true
}

Ça marche pour moi!


1
fsockopen () [function.fsockopen]: php_network_getaddresses: échec de getaddrinfo: aucun hôte de ce type n'est connu. - Si je rencontre cette erreur, quelle en est la raison et que faut-il faire?
Choudhury Saadmaan Mahmid

1
"Works for me" n'est qu'une information anecdotique, mais pas vraiment une explication. Le port et le mot de passe smtp seraient trompeurs pour la plupart des utilisateurs.
mario

Qu'est-ce que "config email" ? Avez-vous une référence?
Peter Mortensen

4

Essaye ça

if ($_POST['submit']) {
    $success= mail($to, $subject, $body, $from);
    if($success)
    { 
        echo '
        <p>Your message has been sent!</p>
        ';
    } else { 
        echo '
        <p>Something went wrong, go back and try again!</p>
        '; 
    }
}

4

Le problème vient peut-être de la configuration du serveur de messagerie. Pour éviter ce type de problèmes ou vous n'avez pas à vous soucier du problème du serveur de messagerie, je vous recommande d'utiliser PHPMailer .

C'est un plugin qui a tout le nécessaire pour envoyer du courrier, et la seule chose que vous devez prendre en compte est d'activer le port SMTP (Port: 25 et 465).

require_once 'PHPMailer/PHPMailer.php';
require_once '/servicios/PHPMailer/SMTP.php';
require_once '/servicios/PHPMailer/Exception.php';

$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
try {
    //Server settings
    $mail->SMTPDebug = 0;
    $mail->isSMTP();
    $mail->Host = 'smtp.gmail.com';
    $mail->SMTPAuth = true;
    $mail->Username = 'correo@gmail.com';
    $mail->Password = 'contrasenia';
    $mail->SMTPSecure = 'ssl';
    $mail->Port = 465;

    // Recipients
    $mail->setFrom('correo@gmail.com', 'my name');
    $mail->addAddress('destination@correo.com');

    // Attachments
    $mail->addAttachment('optional file');         // Add files, is optional

    // Content
    $mail->isHTML(true);// Set email format to HTML
    $mail->Subject = utf8_decode("subject");
    $mail->Body    = utf8_decode("mail content");
    $mail->AltBody = '';
    $mail->send();
}
catch (Exception $e) {
    $error = $mail->ErrorInfo;
}

1
L'IANA a remplacé le port 465 par le port 587. Il s'agit du port de soumission de courrier par défaut. Lorsqu'un client de messagerie ou un serveur sortant soumet un courrier électronique à acheminer par un serveur de messagerie approprié, il doit toujours utiliser le port SMTP 587 comme port par défaut. Voir mailgun.com/blog/which-smtp-port-understanding-ports-25-465-587 . Un conseil avisé: n'ouvrez pas les ports de votre ordinateur si vous n'êtes pas complètement au courant de ce que vous faites!
Harm

3

Assurez-vous que Sendmail est installé sur votre serveur.

Si vous avez vérifié votre code et vérifié qu'il n'y a rien de mal à cela, allez dans / var / mail et vérifiez si ce dossier est vide.

S'il est vide, vous devrez faire:

sudo apt-get install sendmail

si vous êtes sur un serveur Ubuntu.


C'est trop grossier pour être utile. Le simple fait d'installer un MTA permettra rarement d'y accéder. Et un guide de configuration complet de sendmail / postfix / qmail serait hors sujet ici.
mario

Ce commentaire fait-il référence à ma réponse? Parce que cela ne m'est pas arrivé et je ne l'ai pas résolu de la même manière. Il y a différentes réponses possibles à la question, la mienne étant l'une d'entre elles après avoir essayé tout ce qui précède dans le passé, ma réponse avait résolu le problème pour moi, alors je l'ai proposée ici comme une autre solution potentielle.
Daniel

Oui bien sûr. C'est l'une des nombreuses réponses possibles. Cependant, c'est toujours le chemin de l'OMI superficielle. Le généraliser en "vous avez besoin d'un MTA" tel que ... - et voici quelques guides de configuration liés ... pourrait cependant être plus pratique.
mario

3

Tout d'abord, vous pourriez avoir trop de paramètres pour la fonction mail () ... Vous pouvez en avoir au maximum cinq, mail(to, subject, message, headers, parameters);

En ce qui concerne la $fromvariable, cela devrait provenir automatiquement de votre hébergeur si vous utilisez le Linux cPanel . Il provient automatiquement de votre nom d'utilisateur et de votre adresse IP cPanel.

$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = 'contact@yoursite.com';
$subject = 'Customer Inquiry';
$body = "From: $name\n E-Mail: $email\n Message:\n $message";

Assurez-vous également que vous disposez de l'ordre correct des variables dans votre fonction mail ().

Dans mail($to, $subject, $message, etc.)cet ordre, sinon il y a une chance que cela ne fonctionne pas.


3

Si vous rencontrez des problèmes pour envoyer des e-mails avec PHP, envisagez une alternative comme PHPMailer ou SwiftMailer .

J'utilise généralement SwiftMailer chaque fois que j'ai besoin d'envoyer des mails avec PHP.


Utilisation de base:

require 'mail/swift_required.php';

$message = Swift_Message::newInstance()
    // The subject of your email
    ->setSubject('Jane Doe sends you a message')
    // The from address(es)
    ->setFrom(array('jane.doe@gmail.com' => 'Jane Doe'))
    // The to address(es)
    ->setTo(array('frank.stevens@gmail.com' => 'Frank Stevens'))
    // Here, you put the content of your email
    ->setBody('<h3>New message</h3><p>Here goes the rest of my message</p>', 'text/html');

if (Swift_Mailer::newInstance(Swift_MailTransport::newInstance())->send($message)) {
    echo json_encode([
        "status" => "OK",
        "message" => 'Your message has been sent!'
    ], JSON_PRETTY_PRINT);
} else {
    echo json_encode([
        "status" => "error",
        "message" => 'Oops! Something went wrong!'
    ], JSON_PRETTY_PRINT);
}

Consultez la documentation officielle pour plus d'informations sur l'utilisation de SwiftMailer.


3

Pour ceux qui ne veulent pas utiliser de mailers externes et qui veulent mail () sur un serveur Linux dédié.

La façon dont les mails PHP sont décrits php.inidans la section[mail function] .

Le paramètre sendmail-pathdécrit la façon dont sendmail est appelé. La valeur par défaut est sendmail -t -i, donc si vous obtenez un travail sendmail -t -i < message.txtdans la console Linux - vous aurez terminé. Vous pouvez également ajouter mail.logau débogage et être sûr que mail () est vraiment appelé.

Différents MTA peuvent être mis en œuvre sendmail. Ils font juste un lien symbolique vers leurs binaires sur ce nom. Par exemple, dans Debian, la valeur par défaut est Postfix . Configurez votre MTA pour envoyer du courrier et testez-le à partir de la console avec sendmail -v -t -i < message.txt. Le fichier message.txtdoit contenir tous les en-têtes d'un message et un corps, l'adresse de destination de l'enveloppe sera prise dans l'en- To:tête. Exemple:

From: myapp@example.com
To: mymail@example.com
Subject: Test mail via sendmail.

Text body.

Je préfère utiliser ssmtp comme MTA car il est simple et ne nécessite pas d'exécuter un démon avec des ports ouverts. ssmtp convient uniquement pour l'envoi de courrier depuis localhost . Il peut également envoyer des e-mails authentifiés via votre compte sur un service de messagerie public. Installez ssmtp et modifiez le fichier de configuration /etc/ssmtp/ssmtp.conf. Pour pouvoir également recevoir du courrier du système local vers des comptes Unix (alertes à la racine des tâches cron, par exemple), configurez le /etc/ssmtp/revaliasesfichier.

Voici ma configuration pour mon compte sur mail Yandex:

root=mymail@example.com
mailhub=smtp.yandex.ru:465
FromLineOverride=YES
UseTLS=YES
AuthUser=abcde@yandex.ru
AuthPass=password

2

Cela n'affectera qu'une petite poignée d'utilisateurs, mais j'aimerais que cela soit documenté pour cette petite poignée. Ce membre de cette petite poignée a passé 6 heures à dépanner un script de messagerie PHP fonctionnel à cause de ce problème.

Si vous allez dans une université qui exécute XAMPP depuis www.AceITLab.com, vous devez savoir ce que notre professeur ne nous a pas dit: le pare-feu AceITLab (et non le pare-feu Windows) bloque MercuryMail dans XAMPP. Vous devrez utiliser un autre client de messagerie, pear travaille pour nous. Vous devrez envoyer à un compte Gmail avec des paramètres de sécurité faibles.

Oui, je sais, cela est totalement inutile pour le courrier électronique du monde réel. Cependant, d'après ce que j'ai vu, les milieux universitaires et le monde réel ont souvent peu de choses en commun.


C'est trop bizarrement spécifique et cela n'aidera personne d'autre. Veuillez utiliser le lien [supprimer] sous votre réponse, s'il vous plaît.
mario

Qu'est-ce que la «poire» dans ce contexte? Vous voulez dire PEAR , le référentiel de logiciels PHP? Ou autre chose? Par exemple, pair ?
Peter Mortensen

Voulez-vous vraiment dire "petit précieux" ? Est-ce quelque chose à souhaiter? Pourquoi?
Peter Mortensen

1

Si vous exécutez ce code sur un serveur local (c'est-à-dire votre ordinateur à des fins de développement), il n'enverra pas l'e-mail au destinataire. Il va créer un .txtfichier dans un dossier nommémailoutput .

Dans le cas où vous utilisez un service de tuyau gratuit, comme 000webhostou hostinger, ces fournisseurs de services désactivent lemail() fonction pour empêcher les utilisations involontaires d'usurpation d'e-mails, de spam, etc. Je préfère que vous les contactiez pour voir s'ils prennent en charge cette fonctionnalité.

Si vous êtes sûr que le fournisseur de services prend en charge la fonction mail (), vous pouvez consulter ce manuel PHP pour plus de référence,

Courrier PHP ()

Pour vérifier la météo, votre service d'hébergement prend en charge la fonction mail (), essayez d'exécuter ce code (n'oubliez pas de changer l'adresse e-mail du destinataire) :

<?php
    $to      = 'nobody@example.com';
    $subject = 'the subject';
    $message = 'hello';
    $headers = 'From: webmaster@example.com' . "\r\n" .
        'Reply-To: webmaster@example.com' . "\r\n" .
        'X-Mailer: PHP/' . phpversion();

    mail($to, $subject, $message, $headers);
?>

1

L' installation de Sendmail pour Debian 10.0.0 ('Buster') était en fait banale!

php.ini

[mail function]
sendmail_path=/usr/sbin/sendmail -t -i
; (Other directives are mostly windows)

Installation standard du paquet sendmail (autorisant «envoyer»):

su -                                        # Install as user 'root'
dpkg --list                                 # Is install necessary?
apt-get install sendmail sendmail-cf m4     # Note multiple package selection
sendmailconfig                              # Respond all 'Y' for new install

Diverses commandes utiles:

which sendmail                              # /usr/sbin/sendmail
which sendmailconfig                        # /usr/sbin/sendmailconfig
man sendmail                                # Documentation
systemctl restart sendmail                  # As and when required

Vérification (de la capacité d'envoyer)

echo "Subject: sendmail test" | sendmail -v <yourEmail>@gmail.com

Ce qui précède a pris environ 5 minutes. Ensuite j'ai perdu 5 heures ... N'oubliez pas de vérifier votre dossier spam !


0

Il existe plusieurs possibilités:

  1. Vous êtes confronté à un problème de serveur. Le serveur n'a pas de serveur de messagerie. Votre courrier ne fonctionne donc pas, car votre code est correct et le courrier fonctionne avec le type.

  2. Vous n'obtenez pas la valeur publiée. Essayez votre code avec une valeur statique.

  3. Utiliser les e-mails SMTP pour envoyer des e-mails ...


0

Vous pouvez utiliser libmail: http://lwest.free.fr/doc/php/lib/index.php3?page=mail&lang=en

include "libmail.php";
$m = new Mail(); // Create the mail
$m->From($_POST['form']);
$m->To($_POST['to']);
$m->Subject($_POST['subject']);
$m->Body($_POST['body']);
$m->Cc($_POST['cc']);
$m->Priority(4);
// Attach a file of type 'image/gif' to be displayed in the message if possible
$m->Attach("/home/leo/toto.gif", "image/gif", "inline");
$m->Send(); // Send the mail
echo "Mail was sent:"
echo $m->Get(); // Show the mail source

5
Important à mentionner: il s'agit simplement d'un mail()wrapper de fonction. Ajoute seulement la construction du message et quelques gadgets.
mario

0

Vous pouvez voir vos erreurs en:

error_reporting(E_ALL);

Et mon exemple de code est:

<?php
    use PHPMailer\PHPMailer\PHPMailer;
    require 'PHPMailer.php';
    require 'SMTP.php';
    require 'Exception.php';

    $name = $_POST['name'];
    $mailid = $_POST['mail'];
    $mail = new PHPMailer;
    $mail->IsSMTP();
    $mail->SMTPDebug = 0;                   // Set mailer to use SMTP
    $mail->Host = 'smtp.gmail.com';         // Specify main and backup server
    $mail->Port = 587;                      // Set the SMTP port
    $mail->SMTPAuth = true;                 // Enable SMTP authentication
    $mail->Username = 'someone@gmail.com';  // SMTP username
    $mail->Password = 'password';           // SMTP password
    $mail->SMTPSecure = 'tls';              // Enable encryption, 'ssl' also accepted

    $mail->From = 'someone@gmail.com';
    $mail->FromName = 'name';
    $mail->AddAddress($mailid, $name);       // Name is optional
    $mail->IsHTML(true);                     // Set email format to HTML
    $mail->Subject = 'Here is the subject';
    $mail->Body    = 'Here is your message' ;
    $mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
    if (!$mail->Send()) {
       echo 'Message could not be sent.';
       echo 'Mailer Error: ' . $mail->ErrorInfo;
       exit;
    }
    echo 'Message has been sent';
?>

1
SMTPDebug = 0n'est pas utile. Un simple "mot de passe" ne fonctionnerait pas non plus avec GMail. Cette réponse ne contribue pas beaucoup ici.
mario

-2

Si votre système sendmail fonctionne, votre code doit être modifié comme suit:

<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];

    $header ="
Content-Type: text/html; charset=UTF-8\r\n
MIME-Version: 1.0\r\n
From: \"$name\" <$email>\r\n
Reply-To: no-reply@yoursite.com\r\n
X-Mailer: yoursite.com mailer\r\n
";

    $to = '"Contact" <contact@yoursite.com>'; 
    $subject = 'Customer Inquiry';
    $body =<<<EOB
<!DOCTYPE html>
<html>
    <body>
        $message
    </body>
</html>
EOB;

    if ($_POST['submit']) {
        if (mail ($to, $subject, $body, $header) !== false) { 
            echo '<p>Your message has been sent!</p>';
        } else { 
            echo '<p>Something went wrong, go back and try again!</p>'; 
        }
    }
?>

Cela vous permet d'envoyer des e-mails HTML.

D'un intérêt notable:

  1. nous avons construit une chaîne multiligne d'en-tête (chaque ligne séparée par \ r \ n);
  2. nous avons ajouté Content-type pour exprimer que nous renvoyons HTML afin que vous puissiez composer de meilleurs e-mails (vous pouvez ajouter le code HTML que vous voulez, y compris CSS, à votre message comme vous le feriez dans la page HTML).

Remarque: la <<<EOBsyntaxe requiert que le dernier marqueur EOB commence comme le début de la ligne et n'a ni espace ni caractère après le point-virgule.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.