Cliftwalker
Cliftwalker

Reputation: 369

Catching PHP mail() errors and showing reasonable user error message

I'm writing a fairly simple register php script that uses PHP's built in mail() function to email the user an activation link.

The problem is that I can catch the normal errors such as email formatting but once it fires off to the server and say a user has put in an email address that fails, I don't know how to catch this error and tell the user whats happened.

For example at the moment I get this:

Warning: mail() [function.mail]: SMTP server response: 554 : Recipient address rejected: Relay access denied in ** on line 70

Any ideas what I could do about errors like this? I'm aware of using the @ symbol to suppress the error but I kinda of want to do more than that and handle the issue.

Upvotes: 10

Views: 46009

Answers (4)

Yotam
Yotam

Reputation: 888

A trivial error which I suffered from, was simply a lack of 'sendmail' in my system. Eventually, I have installed exim4 and configured it - and then php's mail(...) worked fine.

See also:

Upvotes: 1

mario
mario

Reputation: 145482

Use the boolean result to detect an error:

$success = @mail(...);

Then you want to find out which internal error caused the problem, so use:

$error = error_get_last();
preg_match("/\d+/", $error["message"], $error);
switch ($error[0]) {
    case 554:
        ...
    default:
        ...

Note that this works with php 5.2 onward only.

There is no way to verify delivery or see transport error mails with PHP. You would need a pop3 polling handler for that.

Upvotes: 22

Jan
Jan

Reputation: 2293

Best would be to use a library like Swift Mailer that throws exceptions that can be easily handled.

Upvotes: -2

Kristoffer Sall-Storgaard
Kristoffer Sall-Storgaard

Reputation: 10636

You want to catch as much as you can before you send off the mail, sanitize your inputs to make sure it really is what you expect it to be

You can use filter_var to check that the email address really is an address, check that integers falls within your allowed range, etc.

Set the mail header from address to a place where you can check for failed deliveries:

$headers = 'From: [email protected]' . "\r\n";

You can also check that mail performed as expected:

if(mail($to,$subject,$message))

And a final thing, you probably don't want to display warnings in a live environment, you can turn those off, either through the ini file or using ini_set.

Upvotes: 0

Related Questions