89

I've been using the PHP mail() function.

If the mail doesn't send for any reason, I'd like to echo the error message. How would I do that?

Something like

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

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

Thanks!

xil3
  • 16,305
  • 8
  • 63
  • 97
Rohan
  • 3,645
  • 4
  • 22
  • 16

8 Answers8

131

If you are on Windows using SMTP, you can use error_get_last() when mail() returns false. Keep in mind this does not work with PHP's native mail() function.

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

With print_r(error_get_last()), you get something like this:

[type] => 2
[message] => mail(): Failed to connect to mailserver at "x.x.x.x" port 25, verify your "SMTP" and "smtp_port" setting in php.ini or use ini_set()
[file] => C:\www\X\X.php
[line] => 2

dukevin
  • 22,384
  • 36
  • 82
  • 111
user2317245
  • 1,465
  • 1
  • 9
  • 4
  • 5
    I assume this only works if you use SMTP (Windows?). On Linux if you use "sendmail" the "mail()" function just returns the exit status of that command: https://github.com/php/php-src/blob/PHP-5.6.25/ext/standard/mail.c#L404 There's no reliable way to get the error message afaik. I tried with this script: https://gist.github.com/njam/a34ecd9ef195c37c8354ab58f7bfcc9b – njam Aug 29 '16 at 11:59
  • 1
    `error_get_last()` return `NULL` !! however mail function returns true ! – Accountant م Jul 29 '18 at 19:57
  • Why does this answer not rise to the top of the thread when it's this popular? I wonder how may people miss it completely. – ashleedawg Dec 01 '18 at 15:30
  • 6
    @ashleedawg - I don't even know how this got so many up-votes. I've never - ever seen error_get_last() work with php's native mail() function. In fact, I just barely set up a bad mailing and tried this one more time just to be sure; I got absolutely nothing. – CreationTribe Jul 10 '19 at 04:59
  • is the line $errorMessage = error_get_last()['message']; just supposed to be $errorMessage = error_get_last(); ? I get an error if I try the first way... – Jabbamonkey Oct 29 '19 at 15:56
  • @Jabbamonkey - I tried the first way, and it works just fine. Maybe something is wrong with your PHP configuration? – Momoro Apr 12 '20 at 06:34
  • @Momoro it depends on your php version if you can directly add the array brackes after the function. if you use older php you must first copy the results of `error_get_last()` into a variable before you can access the 'message' part of the array. – Radon8472 Sep 17 '20 at 08:30
  • in addition this not working in linux (tested on ubuntu), it can be really misleading - eg a deprecation notice thrown elsewhere will not break code execution, but will be returned here as last error. Also worth to notice, SMTP and smtp_port ini options are exclusive to win32, as noted in default ini files – CT. Apr 13 '21 at 15:20
18

sending mail in php is not a one-step process. mail() returns true/false, but even if it returns true, it doesn't mean the message is going to be sent. all mail() does is add the message to the queue(using sendmail or whatever you set in php.ini)

there is no reliable way to check if the message has been sent in php. you will have to look through the mail server logs.

Sergey Eremin
  • 10,994
  • 2
  • 38
  • 44
6

In my case, I couldn't get the error message in my PHP script no matter what I do (error_get_last(), or ini_set('display_errors',1);) don't show the error message

according to this post

The return value from $mail refers only to whether or not your server's mailing system accepted the message for delivery, and does not and can not in any way know whether or not you are providing valid arguments. For example, the return value would be false if sendmail failed to load (e.g. if it wasn't installed properly), but would return true if sendmail loaded properly but the recipient address doesn't exist.

I confirm this because after some failed attempts to use mail() in my PHP scripts, it turns that sendmail was not installed on my machine, however the php.ini variable sendmail_path was /usr/sbin/sendmail -t -i

1- I installed sendmail from my package manager shell> dnf install sendmail

2- I started it shell> service sendmail start

3- Now if any PHP mail() function fails I find the errors of the sendmail program logged under /var/mail/ directory. 1 file per user

For example this snippet is taken from my /var/mail/root file

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)

My system is linux Fedora 28 with apache2.4 and PHP 7.2

Accountant م
  • 6,975
  • 3
  • 41
  • 61
5

There is no error message associated with the mail() function. There is only a true or false returned on whether the email was accepted for delivery. Not whether it ultimately gets delivered, but basically whether the domain exists and the address is a validly formatted email address.

Joseph
  • 1,988
  • 14
  • 21
4

You can use the PEAR mailer, which has the same interface, but returns a PEAR_Error when there is problems.

Alex M
  • 3,506
  • 2
  • 20
  • 23
3
$e=error_get_last();
if($e['message']!==''){
    // An error function
}

error_get_last(); - return the last error that occurred

  • 7
    You should add some explanation with your code it could help others in the future. [answer] – cosmoonot Apr 20 '17 at 06:03
  • 2
    Agree with previous comment. Please edit your answer to include some explanation. Code-only answers do very little to educate future SO readers. Your answer is in the moderation queue for being low-quality. – mickmackusa Apr 20 '17 at 07:37
0

Try this. If I got any error on any file then I got error mail on my email id. Create two files index.php and checkErrorEmail.php and uploaded them to your server. Then load index.php with your browser.

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");


?>
Micha Wiedenmann
  • 19,979
  • 21
  • 92
  • 137
Pradeep
  • 27
0

As the others have said, there is no error tracking for send mail it return the boolean result of adding the mail to the outgoing queue. If you want to track true success failure try using SMTP with a mail library like Swift Mailer, Zend_Mail, or phpmailer.

prodigitalson
  • 60,050
  • 10
  • 100
  • 114