Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a bug in the PHP mail() function?

Tags:

php

email

I hoping someone will be able to help me, as I'm at a loss as to what is causing the problem. Our website has a contact us form, with fields for name, email, kid name, kid ID, & message.

When the form submits, the server side php code validates the form fields, & if all is good, uses the built in php mail() function to send 2 emails.

Email 1 goes to an inbox on a hosted exchange server containing the values in the form fields.

Email 2 goes to the person submitting the form saying thanks - we'll get back to you shortly.

For email 1, the From, Reply-To, & Return-Path headers are set to the email entered in the form, & the To param in the mail() function is the email address of the inbox of the hosted exchange server.

For email 2, the From, Reply-To, & Return-Path headers are set to the email address of the inbox on the hosted exchange server, & the To param in the mail() function is the email address entered in the form.

The website's host has the MX, PTR, SPF, & TXT records set up properly to allow emails to be sent to & from the email address of the inbox of the hosted exchange server. The website's host uses QMail as the SMTP service that actually sends the emails, & in all tests, QMail is receiving a success when sending both email 1 & 2. There is no error issued by the mail() function.

Local tests were done with IE8, Chrome, & FF3.6.17. The code was not changed between tests showing this problem.

In all test cases, email 2 (back to the person submitting the form) is sent just fine. Email 1, on the other hand, is only intermittently working. The general pattern is that the 1st time the contact form is used with each distinct email address in the form, the email is sent fine, & the headers & to are correct.

The 2nd time the contact form is used with a previously used email address in the form, the To param is set to the email address in the form, the headers are all blank, & in spite of the To email address being incorrect, the email

is not received. The website's host's support staff may have found another potential symptom, which is that after clearing cookies, all the email 2's got through ok. However, the page does not use any cookies in relation to the form. Lastly, I tried again a while (30 mins?) after email 2's weren't getting through, then another try worked, after which the email 2's screwed up as described above again.

Is there a known bug with php's mail() function along these lines? Is there a maximum frequency at which mail() can be used? I'm at a loss as to why the code sometimes works, & sometimes doesn't. The website's host's staff are at a loss, as well. Trying to google this issue seems to turn up forums of people saying to use different modules (Swift Mailer, PHPMailer, Pear Mail, etc.), but as the website is live, I'm wary that rebuilding the automated emailing code will

introduce errors beyond the one described above.

... edited 6jun11 ...

sorry, didn't know I could edit my post...

Here's the most pertinent code:

function UserToSiteEmail( $name, $fromEmail, $message, $kidID, $kidName )
{
    $subject = "Face of Kinder - contact us";
    $headers = GetEmailHeaders($fromEmail);
    $imageFilename = constant("URL_ROOT")."/kidimages/".$kid->ImageFilename;
    $profileUrl = constant("URL_ROOT")."/profile.php?k=".$kid->KidID;
    $body = file_get_contents("EmailTemplates/ContactUs.html");
    $body = str_replace("#FromName#",$name,$body);
    $body = str_replace("#FromEmail#",$fromEmail,$body);
    $body = str_replace("#KidName#",$kidName,$body);
    $body = str_replace("#KidID#",$kidID,$body);
    $body = str_replace("#Message#",$message,$body);
    $body = str_replace("#SiteRoot#",constant("URL_ROOT"),$body);
    return mail(constant("FROM_EMAIL"),$subject,$body,$headers);
}

function GetEmailHeaders( $fromEmail )
{
    $headers = "From: Face of Kinder <" . $fromEmail . ">" . PHP_EOL;
    $headers .= "Reply-To: " . $fromEmail . PHP_EOL;
    $headers .= "Return-Path: " . $fromEmail . PHP_EOL;
    $headers .= 'MIME-Version: 1.0' . PHP_EOL;
    $headers .= 'Content-type: text/html; charset=iso-8859-1' . PHP_EOL;

    return $headers;
}

The UserToSiteEmail() funct uses the data from the contact us form, where the $fromEmail param is the email entered in the form. From what Rackspace could find in the QMail logs was that when the 2nd use of the same email in the contact us form gets submitted, the email in the form ends up in the To field, not in the headers, & the email inbox's address didn't show anywhere (not even the headers - i.e., it didn't swap). This is even though the same code correctly put the form's email into the header, & the email inbox's address in the To field on the 1st submitting of the form (per browser).

I can add the HTML side of the form if needed, but in terms of its process, after the form is submitted back to itself, after validating & emailing, the php redirects to a thanks page. I'm not certain how GET & POST variables would persist after the thank you page, as the only way back to the page is to click the link for the contact form again. To see the current process (without the problem - as it only seems to crop up when using the email inbox's domain), here's a link to a page with the contact us link in the footer: http://www.faceofkinder.com/home.php.

I figure the QMail log indicating the fail could help, too...

342812-web2 qmail-queue-handlers[1147]: Handlers Filter before-queue for qmail started ...
342812-web2 qmail-queue-handlers[1147]: from=
342812-web2 qmail-queue-handlers[1147]: [email protected]
342812-web2 qmail-queue-handlers[1147]: hook_dir = '/var/qmail//handlers/before-queue'
342812-web2 qmail-queue-handlers[1147]: recipient[3] = '[email protected]'
342812-web2 qmail-queue-handlers[1147]: handlers dir = '/var/qmail//handlers/before-queue/recipient/[email protected]'
342812-web2 qmail-queue-handlers[1147]: starter: submitter[1148] exited normally
342812-web2 qmail: 1307092428.798059 bounce msg 18353656 qp 1147
342812-web2 qmail: 1307092428.798116 end msg 18353656
342812-web2 qmail: 1307092428.798338 new msg 18353663
342812-web2 qmail: 1307092428.798366 info msg 18353663: bytes 4902 from <> qp 1148 uid 2522
342812-web2 qmail: 1307092428.800937 starting delivery 2481: msg 18353663 to remote [email protected]
342812-web2 qmail: 1307092428.801071 status: local 0/10 remote 2/20
342812-web2 qmail-remote-handlers[1149]: Handlers Filter before-remote for qmail started ...
342812-web2 qmail-remote-handlers[1149]: from=
342812-web2 qmail-remote-handlers[1149]: [email protected]
342812-web2 qmail: 1307092430.526801 delivery 2481: success: 98.129.184.131_accepted_message./Remote_host_said:_250_OK_BD/F0-16184-DC5A8ED4/
342812-web2 qmail: 1307092430.526909 status: local 0/10 remote 1/20
342812-web2 qmail: 1307092430.526938 end msg 18353663
342812-web2 qmail: 1307092430.576988 delivery 2480: success: 98.129.184.131_accepted_message./Remote_host_said:_250_2.0.0_Ok:_queued_as_6D/F0-16184-DC5A8ED4/
  • O8
like image 809
Orion Avatar asked Jun 03 '11 12:06

Orion


1 Answers

Based on your description, I suspect the problem could be with the line ending of your headers.

From the manual:

additional_headers (optional)

... Multiple extra headers should be separated with a CRLF (\r\n).

... Note: If messages are not received, try using a LF (\n) only. Some poor quality Unix mail transfer agents replace LF by CRLF automatically (which leads to doubling CR if CRLF is used). This should be a last resort, as it does not comply with » RFC 2822.

I am not sure what you defined as PHP_EOL, but you could try CRLF or LF alone.

like image 152
Sylverdrag Avatar answered Sep 22 '22 07:09

Sylverdrag