web-dev-qa-db-fra.com

WordPress refuse d'envoyer du courrier, "... votre hôte peut avoir désactivé la fonction mail ()"

J'ai récemment mis en place une zone de commentaires sur mon site Web et j'ai essayé de faire fonctionner la notification par courrier électronique. Il ne semble pas vouloir envoyer de notifications par courrier électronique lorsque de nouveaux commentaires sont faits.

Juste pour voir si PHP peut envoyer des emails, j'ai essayé de réinitialiser le mot de passe (car vous obtiendrez un nouveau mot de passe par courrier), et j'ai reçu le message suivant:

L'e-mail n'a pas pu être envoyé. Raison possible: votre hôte peut avoir désactivé la fonction mail ()

J'ai vérifié les cases à cocher dans Paramètres -> Discussion, et l'e-mail est valide, donc ce n'est pas un problème de réglage. J'ai essayé de créer un fichier PHP et de l'envoyer à l'aide de mail(). L'envoi a abouti. Il doit donc y avoir quelque chose de bizarre avec WordPress.

Des idées?

9
qwerty

Étape par étape: Recherchez d’abord le fichier dans lequel le message d’erreur apparaît. J'utilise Notepad ++ et le CTRL + F commande pour rechercher dans les fichiers. Il est conseillé de ne rechercher que les premiers mots du message d'erreur, car certains messages d'erreur sont combinés avec des messages différents.

Votre message d'erreur apparaît dans wp-login.php et sainte chance, uniquement là-bas. Voyons donc pourquoi cette erreur pourrait se produire.

if ( $message && !wp_mail($user_email, $title, $message) )

Il y a deux conditions. $message doit être vrai (pas une chaîne vide, pas faux, pas nul, etc.). Et wp_mail() ne devrait pas retourner false.

Une ligne ci-dessus contient un filtre $message = apply_filters('retrieve_password_message', $message, $key);. Il est donc possible qu’un plugin (ou un thème) utilise ce filtre et renvoie une valeur qui n’est pas vraie (chaîne vide, faux, null, etc.).

Mais il est beaucoup plus facile de vérifier si wp_mail() fonctionne ou non. Ecrivez un petit plugin pour vous envoyer un mail de test:

<?php
/**
 * Plugin Name: Stackexchange Testplugin
 * Plugin URI:  http://yoda.neun12.de
 * Description: Send me a test email
 * Version:     0.1
 * Author:      Ralf Albert
 * Author URI:  http://yoda.neun12.de
 * Text Domain:
 * Domain Path:
 * Network:
 * License:     GPLv3
 */

namespace WordPressStackexchange;

add_action( 'init', __NAMESPACE__ . '\plugin_init' );

function plugin_init(){
    $to      = '[email protected]';
    $subject = 'Testemail';
    $message = 'FooBarBaz Testmail is working';

    wp_mail( $to, $subject, $message );
}

(Ceci est du code PHP 5.3. Si vous utilisez PHP 5.2, supprimez les éléments d'espace de noms)

Le plugin doit envoyer un testmail immédiatement après l'activation. Sinon, appeler des pages principales (par exemple, un tableau de bord) devrait le faire.

Si le testmail n'arrive pas, vous avez probablement un problème avec wp_mail(). Alors, activez le débogage:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', true );
@ini_set( 'display_errors',1 );

Mettez ce code dans votre wp-config.php et réessayez de vous envoyer un testmail. Vous devriez maintenant recevoir des messages d'erreur et les enregistrer dans wp-content/debug.log (le journal de débogage peut devenir très volumineux s'il y a plus d'erreurs causées par des plugins et/ou des thèmes).

À ce stade, vous avez de bonnes informations si wp_mail() échoue et si oui, pourquoi. Si wp_mail() fonctionne correctement et que le testmail est arrivé, retournez au début de la page et découvrez pourquoi $message n'est pas vrai.

Si vous avez des problèmes avec wp_mail(), gardez à l'esprit que wp_mail() n'utilise pas la fonction PHP mail(). WordPress utilise une classe PHP ( PHPMailer ). Peut-être avez-vous juste besoin de n plugin pour utiliser SMTP au lieu de sendmail. Ou le problème est situé à un autre endroit. Nous ne savons pas Vous devez enquêter.

9
Ralf912

Ceci est un message d'erreur super gênant car il pourrait être beaucoup choses, et il ne révèle pas l'erreur réelle (qui est souvent réduite au silence dans d'autres parties du code).

Cette erreur apparaît lorsque la fonction wp_mail() renvoie false, ce qui peut se produire si phpmailer->Send() renvoie false ou déclenche une exception.


Comment afficher les avertissements de la fonction mail() de PHP

Celles-ci sont normalement désactivées par défaut, mais malheureusement, WordPress ne les capture jamais. Pour les afficher, supprimez simplement les signes @ de @mail(... dans wp-includes/class-phpmailer.php dans la fonction mailPassthru():

if (ini_get('safe_mode') || !($this->UseSendmailOptions)) {
    $rt = @mail($to, $this->encodeHeader($this->secureHeader($subject)), $body, $header);
} else {
    $rt = @mail($to, $this->encodeHeader($this->secureHeader($subject)), $body, $header, $params);
}


Comment traquer les autres causes possibles:

  1. Ajoutez une seule ligne au bas de wp_mail() dans /wp-includes/pluggable.php:

    // Send!
    try {
        return $phpmailer->Send();
    } catch ( phpmailerException $e ) {
        //------------- This next line is the one to add -------------------
        if (WP_DEBUG) echo '<pre>' . esc_html(print_r($e, TRUE)) . '</pre>';
        return false;
    }
    
  2. Il affichera tous les détails de l'endroit où l'exception a été levée. Malheureusement, il contient parfois ce message d’exception inutile: " Impossible d’instancier la fonction mail ". Oui merci WordPress, c'est vraiment utile.

  3. En examinant l'exception, vous pouvez trouver le numéro de ligne de l'erreur et, espérons-le, la retrouver dans le code pour trouver la cause réelle.

Bonne chance. Espérons que WordPress améliore la gestion des erreurs de messagerie à un moment donné dans l’avenir.

2
Simon East

J'ai le même problème avec le serveur Ubuntu sur Amazon EC2.I obtenir un problème lors de l'utilisation du lien de réinitialisation du mot de passe et d'autres e-mails de notification ne fonctionnaient pas.

Voici donc des solutions qui ont fonctionné pour moi.Word-press a utilisé la fonction wp_mail() pour envoyer des courriels nécessitant une classe PHPMailer qui utilisait le mail php stocké dans /usr/sbin/sendmail.

Utilisez cette fonction php simple d'abord pour vérifier le courrier php

<?php
$to = "[email protected]";
$subject = "Test Email Function";
$txt = "Hello world!";
$headers = "From: [email protected]" . "\r\n" .
"CC: [email protected]";

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

Si cela ne fonctionne pas, vous devez installer php mailer. Utilisez cette commande pour installer le courrier php sur le serveur Ubuntu.

Sudo apt-get install sendmail

Ensuite, vérifiez les fonctions de messagerie Word-press.

2
CyberAbhay

Si les autres bonnes réponses ne vous aident pas, essayez ceci:

J'ai rencontré ce même problème et rien de ce que j'ai pu trouver dans aucune des suggestions de WordPress ne l'a résolu pour moi.

Ensuite, j'ai commencé à rechercher si l'installation PHP avait elle-même désactivé la fonction de messagerie, mais rien de tout cela ne fonctionnait. Tout avait l'air d'être configuré correctement.

Tous ces problèmes ont commencé pour moi lorsque j'ai mis à niveau mon serveur vers CentOS 7, qui utilise SELinux (Security Enhanced Linux). Ce que j'ai appris ces dernières semaines avec SELinux, c'est que si quelque chose ne fonctionne pas, tout ressemble à cela devrait fonctionner ... cela signifie que SELinux vous bloque silencieusement et secrètement en arrière-plan.

Et alto.

Si vous utilisez un système d'exploitation qui utilise SELinux, exécutez la commande suivante en tant qu'utilisateur root:

setsebool -P httpd_can_sendmail=1

Il existe un paramètre de sécurité qui empêche de manière inhérente le serveur Web d'envoyer un courrier électronique. Lorsque vous tournez ce commutateur et dites à SELinux que le serveur Web peut envoyer un courrier électronique, tout fonctionne soudainement.

1
Kenny Wyland

Je me suis heurté à cela aujourd'hui; dans mon cas, la situation s'est produite car le fichier hosts du serveur a le même nom de domaine que l'adresse de messagerie, pointant vers localhost. L'enregistrement mx pointe vers un autre serveur, mais le fichier hosts remplace le DNS et WP tente de livrer le courrier localement. La suppression du domaine du fichier hosts et le redémarrage de sendmail ont résolu ce problème.

0
user16081

J'ai eu la même erreur, les deux fonctions (mail et wp_mail) fonctionnaient, mais j'avais toujours cette erreur gênante. La solution était très facile, mais il m'a fallu quelques heures pour trouver la raison. Je vais donc partager ici ma solution sur le problème qui pourrait être (ou ne pas être) le même avec le vôtre.

J'ai essayé la fonction mail () et cela a fonctionné, mais lorsque vous le testez, vous ne spécifiez pas le dernier paramètre appelé "paramètres" dans la fonction mail (). Et WP l'utilise.

@mail("[email protected]",$title,$body,$headers,"[email protected]");

Donc, fondamentalement, ce paramètre ("[email protected]") avec l'indicateur "-f" permet à la fonction mail () de vérifier si l'adresse électronique "[email protected]" est répertoriée dans la liste "emails fiables".

Donc, si ce n'est pas le cas, il renvoie false, ce qui fait que wp_mail () renvoie false et conduit au message d'erreur.

La solution consiste donc à demander à l’organisateur de le faire pour vous, ou si vous utilisez cPanel, ajoutez simplement un compte de messagerie pour cette adresse et il sera automatiquement ajouté à la "liste de confiance".

0
user3696815

Je ne sais pas si cela vous concerne ou non, mais comme aucune réponse n’a été choisie, je me suis dit que je pouvais essayer une fois.

En fait, je rencontrais exactement le même problème depuis mon hôte OpenShift qui a soudainement cédé le pas et cessé d’envoyer des courriers. En fouillant dans le code et le codex, j'ai appris à connaître la fonction wp_mail () et finalement, Google m'a conduit ici et j'ai vu comment il pourrait être remplacé.

En me basant sur la réponse de @ Ralf912, j’ai un peu modifié le script pour que le code utilise l’API Web de sendgrid.com pour envoyer des e-mails au lieu de celui de wordpress par défaut (ce que je suppose:

<?php

function sendgridmail($to, $subject, $message, $headers)
{
    $url = 'https://api.sendgrid.com/';
    //$user = 'yourUsername';
    //$pass = 'yourPassword';

    $params = array(
        'api_user'  => $user,
        'api_key'   => $pass,
        'to'        => $to,
        'subject'   => $subject,
        'html'      => '',
        'text'      => $message,
        'from'      => '[email protected]',
      );


    $request =  $url.'api/mail.send.json';

    // Generate curl request
    $session = curl_init($request);
    // Tell curl to use HTTP POST
    curl_setopt ($session, CURLOPT_POST, true);
    // Tell curl that this is the body of the POST
    curl_setopt ($session, CURLOPT_POSTFIELDS, $params);
    // Tell curl not to return headers, but do return the response
    curl_setopt($session, CURLOPT_HEADER, false);
    curl_setopt($session, CURLOPT_RETURNTRANSFER, true);

    // obtain response
    $response = curl_exec($session);
    curl_close($session);

    // print everything out
    //print_r($response);
}

//only for testing:
/*$to      = '[email protected]';
$subject = 'Testemail';
$message = 'It works!!';
echo 'To is: ' + $to;
#wp_mail( $to, $subject, $message, array() );
sendgridmail($to, $subject, $message, $headers);
print_r('Just sent!');*/

if (!function_exists('wp_mail')) {
    function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
    {
        // use the PHP GnuPG library here to send mail.
        sendgridmail($to, $subject, $message, $headers);
    }
}

function plugin_init()
{
   /* $to      = '[email protected]';
    $subject = 'Testemail';
    $message = 'It works Live!';
    //echo 'To is: ' + $to;
    wp_mail( $to, $subject, $message, array() );
    //print_r('Just sent!');*/
}

Et ça a marché!

0
Prahlad Yeri