6

Some days ago when using mail() I had it working.

But now it doesn't work. And I don't know what the problem is.

$to      = 'testmail@gmail.com';
$subject = 'the subject';
$message = 'hello';
$headers = 'From: sender@gmail.com' . "\r\n" .
    'Reply-To: sender@gmail.com' . "\r\n" .
    'X-Mailer: PHP/' . phpversion();

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

$mail_sent = @mail( $to, $subject, $message, $headers ); 
echo $mail_sent ? "Mail sent" : "Mail failed";

It displays "Mail sent".

I haven't touched anything in Apache or this code. I have tested the code in an empty PHP file with the same result. How can I debug this problem?

ЯegDwight
  • 24,821
  • 10
  • 45
  • 52
ajsie
  • 77,632
  • 106
  • 276
  • 381
  • I'm assuming it doesn't actually send the e-mail? – Jeff Rupert Dec 12 '09 at 05:29
  • thats the problem..why has it stopped working. how do i send it?=) – ajsie Dec 12 '09 at 05:29
  • same untouched code, same configuration, different day and it now doesn't work? .. what's your mail engine sendmail or .. ?? – Scott Evernden Dec 12 '09 at 05:47
  • im a noob at this. how can i check what my mail engine is? and which ones are there. i think it is sendmail. can i use it in the command line to debug? – ajsie Dec 12 '09 at 05:51
  • 2
    Do you get an error message if you remove the "@" before mail()? @ is the error-suppression operator, so if you want to debug something the first thing you should do is get rid of the @. – Jordan Running Dec 12 '09 at 05:54
  • 1
    i have deleted the @ and also turned on E_ALL in php.ini but no warnings/error/notices were shown. – ajsie Dec 12 '09 at 06:00
  • Which linux distribution (if it is linux?) do you use? What does ` – VolkerK Jan 03 '10 at 01:50

6 Answers6

11

When you send an email using mail() php hands the data over to the application you configured in sendmail_path, i.e. it spawns a new process for <sendmail_path> and passes some parameters and the email data. This application is supposed to inject the email into the queue of a Mail Transfer Agent (MTA).
The return value of php's mail() function "only" reflects if php was able to spawn that process, stream the data to it and the process exits without an error code. I.e. mail()==true only tells you that the email was (supposedly) injected into the queue of the first MTA on the route.

The MTA then decides what to do with the email. You're probably not working for google and your own MTA is not "within" gmail.com. So your MTA has to send it to the next MTA on the path to gmail.com (forward-path). This may work or not, but mail()===true doesn't tell you anything about that.
Relaying the mail from MTA to MTA may fail on any of the steps. And when the mail finally arrives "at" gmail.com the last MTA or the Mail Delivery Agent (MDA) may also reject it for various reasons.

If an error occurs the "current" MTA may (actually it must, but that's assuming all is configured well ;-)) send back an error report. This error report follows the forward-path but in reverse order (reverse-path) and finally (or "hopefully") the originator receives an "undeliverable mail" email.

(and that's the short version. It's probably inaccurate and I'm neither an admin nor an email/smtp expert ;-))

So...what can you do?

  1. Tell us more about your server. Is it your own (home/test) server? Which operating system. Do you know which "mailing system" was installed (sendmail, qmail, ...)? Who configured it?

  2. Ask on Server Fault how to set up your server's mailing system, how it might try to tell you if something went wrong and how to convince google to accept your emails.

  3. Eliminate the first MTA or more to the point let the php script itself become the first MTA. You can do so by using e.g. Swiftmailer (utilizing its smtp transport module) instead of mail(). This way your server's local mail system doesn't have to work properly. The script will "directly" contact google's SMTP server, authenticate "you" and deliver the mail to google. It still doesn't guarantee the mail will be delivered but it much more likely an error is reported immediately to your script, i.e. if swiftmailer signals "Ok" it's much more likely it really is ok than mail() returning "true".

VolkerK
  • 95,432
  • 20
  • 163
  • 226
11

Could it be that E-Mails are being sent fine, but are caught by a spam filter? If this could be, allow me to cross-post myself:


A few bullet points (Assuming that mail() returns true and there are no errors in the error log) :

  • Does the sender address ("From") belong to a domain on your server? If not, make it so.
  • Is your server on a blacklist (e.g. check IP on spamhaus.org)? This is a remote possibility with shared hosting.
  • Are mails filtered by a spam filter? Open an account with a freemailer that has a spam folder and find out. Also, try sending mail to an address without a spam filter.
  • Do you possibly need the fifth parameter "-f" of mail() to add a sender address? (See mail() command in the PHP manual)
  • If you have access to log files, check those, of course, as suggested above.
  • Do you check the "from:" address for possible bounce mails ("Returned to sender")? You can also set up a separate "errors-to" address.

For german speakers, I have written a quite exhaustive "what to do" on this issue some time ago. See here.

Community
  • 1
  • 1
Pekka
  • 442,112
  • 142
  • 972
  • 1,088
  • 1
    The first bullet point is obviously being violated (as mmsmatt pointed out also). Don't say `From: someone@gmail.com` when your server is obviously not Gmail. – philfreo Dec 28 '09 at 05:42
1

Well, I bet you are using free/commercial server which is managed by some other guys. Unfortunately sometimes the server setting is not correct so that you cannot get the email even you have followed the correct php syntax. Try contacting its customer service center and let them do the diagnostic stuff for you.

This happens to my server for one time (justhost is to blame!) so this might be helpful to you.

check these attributes from your phpinfo(); (if it allows you to see that)

sendmail_from   no value    no value
sendmail_path   /usr/sbin/sendmail -t -i    /usr/sbin/sendmail -t -i

Chances are, these attributes are not configured well.

I don't see anything wrong with your php statement:)

edited : you can also upload the mail script written by another language (Perl is the best as most Linux servers have it installed as default). See if you can send email from there. If so, then I assume it is the server configuration error(php.ini problem?), not yours. If the Perl script cannot send email either, well... let guys in the customer service center know and see if you can get your money back:)

Michael Mao
  • 9,878
  • 23
  • 75
  • 91
1

The SMTP server handling your mail might be rejecting the message because it claims to come from gmail.com.

Try changing the 'From' field in $headers to an address from your domain.

Matt Stephenson
  • 8,442
  • 1
  • 19
  • 19
1

If you're right, and code which used to work is no longer working, then something outside your code must have changed. There's at least 2 MTAs (one local, and one remote) which might be interfering with your email. If you control the local one, then checks the queue and logs to see if it is being forwarded.

Unfortunately, because of the volume and nature of spam, lots of people invent non-standardized methods of dealing with it - RBLs, RMX, domain Keys, sender id, bayesian filters....there's nothing intrinsically wrong with these approaches but for the fact they are unilaterally applied by service providers often without the knowledge, let alone consent of the service users. And providers are usually very secretive about the provisions they've put in place. But if you're sending to gmail then it will probably be bayesian-like filtering systems they use - HAVE YOU CHECKED THE SPAM FOLDER?

So it is very probable that even if the change has been applied somewhere beyond your sphere of influence, it may not be an absolute block, however routing your mail through the mail server may well require a lot of experimentation.

C.

symcbean
  • 47,736
  • 6
  • 59
  • 94
0

Try adding -f parameter to the mail() call

Signup with email authentication, only 30% are activated?

Community
  • 1
  • 1
Ivan Krechetov
  • 18,802
  • 8
  • 49
  • 60