Як отримати повідомлення про помилку функції mail ()?


80

Я використовую функцію PHP mail().

Якщо пошта не надсилається з будь-якої причини, я хотів би повторити повідомлення про помилку. Як би я це зробив?

Щось на зразок

$this_mail = mail('example@example.com', 'My Subject', $message);

if($this_mail) echo 'sent!';
else echo error_message;

Дякую!

Відповіді:


118

Якщо ви використовуєте Windows за допомогою SMTP, ви можете використовувати, error_get_last()коли mail()повертає false. Майте на увазі, це не працює з власною функцією поштової PHP ().

$success = mail('example@example.com', 'My Subject', $message);
if (!$success) {
    $errorMessage = error_get_last()['message'];
}

З print_r(error_get_last()), ви отримуєте щось подібне:

[тип] => 2
[повідомлення] => пошта (): Не вдалося підключитися до поштового сервера через порт "xxxx" 25, перевірте налаштування "SMTP" та "smtp_port" у php.ini або використовуйте ini_set ()
[файл] = > C: \ www \ X \ X.php
[рядок] => 2


4
Я припускаю, що це працює, лише якщо ви використовуєте SMTP (Windows?). У Linux, якщо ви використовуєте "sendmail", функція "mail ()" просто повертає статус виходу цієї команди: github.com/php/php-src/blob/PHP-5.6.25/ext/standard/mail.c# L404 Немає надійного способу отримати повідомлення про помилку afaik. Я пробував із цим сценарієм: gist.github.com/njam/a34ecd9ef195c37c8354ab58f7bfcc9b
njam

error_get_last()повернись NULL!! однак функція пошти повертає true!
Бухгалтер م

Чому ця відповідь не піднімається до кінця теми, коли вона така популярна? Цікаво, як люди можуть це повністю пропустити.
ashleedawg

4
@ashleedawg - я навіть не знаю, як це набрало стільки голосів. Я ніколи - ніколи не бачив, щоб error_get_last () працював із власною функцією mail () php. Насправді я просто ледве встановив погану розсилку і спробував ще раз, щоб бути впевненим; Я абсолютно нічого не отримав.
CreationTribe

є рядок $ errorMessage = error_get_last () ['повідомлення']; просто повинен бути $ errorMessage = error_get_last (); ? Я отримую повідомлення про помилку, якщо спробувати першим шляхом ...
Jabbamonkey

15

надсилання пошти у php - це не одноетапний процес. mail () повертає true / false, але навіть якщо воно повертає true, це не означає, що повідомлення буде надіслано. все, що робить mail () - це додавання повідомлення до черги (за допомогою sendmail або того, що ви встановили в php.ini)

немає надійного способу перевірити, чи надіслано повідомлення у php. вам доведеться переглянути журнали поштового сервера.


3
а де журнал пошти?
Махефа

5

У моєму випадку я не міг отримати повідомлення про помилку у своєму PHP-скрипті, незалежно від того, що я роблю ( error_get_last(), абоini_set('display_errors',1); ) не показую повідомлення про помилку

згідно з цим постом

Повернене значення з $ mail стосується лише того, чи прийняла повідомлення повідомлення для доставки поштова система вашого сервера, і ні в якому разі не може і не може знати, чи надаєте ви дійсні аргументи чи ні. Наприклад, повернене значення буде хибним, якщо sendmail не вдалося завантажити (наприклад, якщо він був встановлений неправильно), але поверне true, якщо sendmail завантажений належним чином, але адреса одержувача не існує.

Я підтверджую це, оскільки після деяких невдалих спроб використання mail()в моїх PHP-скриптах виявляється, що sendmailце не було встановлено на моїй машині, проте змінна php.ini sendmail_pathбула/usr/sbin/sendmail -t -i

1- Я встановив sendmail від свого менеджера пакетів shell> dnf install sendmail

2- Я це розпочав shell> service sendmail start

3- Тепер, якщо яка-небудь mail()функція PHP виходить з ладу, я виявляю помилки sendmailпрограми, в яку входить/var/mail/ каталозі. 1 файл на користувача

Наприклад, цей фрагмент взято з мого /var/mail/rootфайлу

The original message was received at Sun, 29 Jul 2018 22:37:51 +0200
from localhost [127.0.0.1]
   ----- The following addresses had permanent fatal errors -----
<no-one@errorerrorerrorerror51248562221e542.com>
    (reason: 550 Host unknown)

Моя система - Linux Fedora 28 з apache2.4 та PHP 7.2


4

Ви можете використовувати поштову програму PEAR , яка має той самий інтерфейс, але повертає PEAR_Error, коли виникають проблеми.


1
А як щодо PHP Mailer ?
s3c

3

З mail()функцією не пов'язано повідомлення про помилку . Існує лише trueабо falseповернення щодо того, чи було прийнято електронне повідомлення до доставки. Не те, чи він в кінцевому рахунку доставляється, а в основному, чи існує домен і чи є адреса правильно відформатованою електронною адресою.


1
$e=error_get_last();
if($e['message']!==''){
    // An error function
}

error_get_last (); - повернути останню помилку, що сталася


6
Додайте пояснення до свого коду, що може допомогти іншим у майбутньому. Як відповісти
cosmoonot

2
Погодьтеся з попереднім коментарем. Будь ласка, відредагуйте свою відповідь, щоб включити пояснення. Відповіді лише за кодами дуже мало допомагають навчати майбутніх читачів SO. Ваша відповідь - в черзі на модерацію за низьку якість.
mickmackusa

0

Як сказали інші, відстеження помилок для відправленої пошти не повертає логічний результат додавання пошти до вихідної черги. Якщо ви хочете відстежити справжній успіх, спробуйте використати SMTP з поштовою бібліотекою, такою як Swift Mailer, Zend_Mail або phpmailer.


0

Спробуйте це. Якщо я отримав будь-яку помилку в будь-якому файлі, я отримав повідомлення про помилку на ідентифікатор електронної пошти. Створіть два файли index.phpта checkErrorEmail.phpзавантажте їх на свій сервер. Потім завантажтеindex.php браузер.

Index.php

<?php
    include('checkErrorEmail.php');
    include('dereporting.php');
    $temp;
    echo 'hi '.$temp;
?>

checkErrorEmail.php

<?php
  // Destinations
  define("ADMIN_EMAIL", "pradeep.callus7@hotmail.com");
  //define("LOG_FILE", "/my/home/errors.log");

  // Destination types
  define("DEST_EMAIL", "1");
  //define("DEST_LOGFILE", "3");

  /* Examples */

  // Send an e-mail to the administrator
  //error_log("Fix me!", DEST_EMAIL, ADMIN_EMAIL);

  // Write the error to our log file
  //error_log("Error", DEST_LOGFILE, LOG_FILE);

  /**
    * my_error_handler($errno, $errstr, $errfile, $errline)
    *
    * Author(s): thanosb, ddonahue
    * Date: May 11, 2008
    * 
    * custom error handler
    *
    * Parameters:
    *  $errno:   Error level
    *  $errstr:  Error message
    *  $errfile: File in which the error was raised
    *  $errline: Line at which the error occurred
    */

  function my_error_handler($errno, $errstr, $errfile, $errline)
  {  
  echo "<br><br><br><br>errno ".$errno.",<br>errstr ".$errstr.",<br>errfile ".$errfile.",<br>errline ".$errline;
      if($errno)
      {
              error_log("Error: $errstr \n error on line $errline in file $errfile \n", DEST_EMAIL, ADMIN_EMAIL);
      }
    /*switch ($errno) {
      case E_USER_ERROR:
        // Send an e-mail to the administrator
        error_log("Error: $errstr \n Fatal error on line $errline in file $errfile \n", DEST_EMAIL, ADMIN_EMAIL);

        // Write the error to our log file
        //error_log("Error: $errstr \n Fatal error on line $errline in file $errfile \n", DEST_LOGFILE, LOG_FILE);
        break;

      case E_USER_WARNING:
        // Write the error to our log file
        //error_log("Warning: $errstr \n in $errfile on line $errline \n", DEST_LOGFILE, LOG_FILE);
        break;

      case E_USER_NOTICE:
        // Write the error to our log file
       // error_log("Notice: $errstr \n in $errfile on line $errline \n", DEST_LOGFILE, LOG_FILE);
        break;

      default:
        // Write the error to our log file
        //error_log("Unknown error [#$errno]: $errstr \n in $errfile on line $errline \n", DEST_LOGFILE, LOG_FILE);
        break;
    }*/

    // Don't execute PHP's internal error handler
    return TRUE;
  }


  // Use set_error_handler() to tell PHP to use our method
  $old_error_handler = set_error_handler("my_error_handler");


?>

4
що таке include ('dereporting.php') ;?
Джон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.