search for in the  
<lzf_optimized_forezmlm_hash>
Last updated: Thu, 19 May 2005

LXII. Mail Functions

Introduction

The mail() function allows you to send mail.

Requirements

For the Mail functions to be available, PHP must have access to the sendmail binary on your system during compile time. If you use another mail program, such as qmail or postfix, be sure to use the appropriate sendmail wrappers that come with them. PHP will first look for sendmail in your PATH, and then in the following: /usr/bin:/usr/sbin:/usr/etc:/etc:/usr/ucblib:/usr/lib. It's highly recommended to have sendmail available from your PATH. Also, the user that compiled PHP must have permission to access the sendmail binary.

Installation

There is no installation needed to use these functions; they are part of the PHP core.

Runtime Configuration

The behaviour of these functions is affected by settings in php.ini.

Table 1. Mail configuration options

NameDefaultChangeableChangelog
SMTP"localhost"PHP_INI_ALL 
smtp_port"25"PHP_INI_ALLAvailable since PHP 4.3.0.
sendmail_fromNULLPHP_INI_ALL 
sendmail_pathNULLPHP_INI_SYSTEM 
For further details and definitions of the PHP_INI_* constants, see the Appendix H.

Here's a short explanation of the configuration directives.

SMTP string

Used under Windows only: DNS name or IP address of the SMTP server PHP should use for mail sent with the mail() function.

smtp_port int

Used under Windows only: Number of the port to connect to the server specified with the SMTP setting when sending mail with mail(); defaults to 25. Only available since PHP 4.3.0.

sendmail_from string

Which "From:" mail address should be used in mail sent from PHP under Windows.

sendmail_path string

Where the sendmail program can be found, usually /usr/sbin/sendmail or /usr/lib/sendmail. configure does an honest attempt of locating this one for you and set a default, but if it fails, you can set it here.

Systems not using sendmail should set this directive to the sendmail wrapper/replacement their mail system offers, if any. For example, Qmail users can normally set it to /var/qmail/bin/sendmail or /var/qmail/bin/qmail-inject.

qmail-inject does not require any option to process mail correctly.

This directive works also under Windows. If set, smtp, smtp_port and sendmail_from are ignored and the specified command is executed.

Resource Types

This extension has no resource types defined.

Predefined Constants

This extension has no constants defined.

Table of Contents
ezmlm_hash -- Calculate the hash value needed by EZMLM
mail -- Send mail


User Contributed Notes
Mail Functions
Andrew W
27-Apr-2005 06:19
I spent weeks trying to work out why PHP couldnt send mail through Exim (called locally) when for all other purposes Exim worked fine.  Here, after hours of work is the answer and I hope it saves someone else some time:

PHP by default calls sendmail/exim/whatever with the options -t & -i

-i is causing Exim to sit there waiting for more input, not detecting the end of the message.  You need to tell it not to use -i by manually specifying the arguments you DO want on sendmail_path like this:

sendmail_path = /path/to/exim -t
pkringle at planetnet dot org
29-Mar-2005 08:45
You want to setup the Return-Path on a email sent, without modifing the php.ini or httpd.conf file.  You can do it in your php code.

EXAMPLE:

mail("$to", "$subject", "$message", "From: $from\nX-Mailer: PHP/ . $phpversion()", "-f $from");

END EXAMPLE:

Notice the "-f" at the end of the function.  This will set the return-path.
edegraaf NO SPAM at gmx NO SPAM dot net
17-Mar-2005 09:23
Be careful with the popen() function when you want execute sendmail or another function.

Many servers on the internet have safe_mode on, and in that case you can only execute functions from one specific directory, specified in safe_mode_exec_dir. So executing /usr/sbin/sendmail is out of the question when safe mode is on.
jdephix at hotmail dot com
02-Mar-2005 03:25
How to add multiple attachment to an email:

An email can be split into many parts separated by a boundary followed by a Content-Type and a Content-Disposition.

The boundary is initialized as follows:
<?php
$boundary
= '-----=' . md5( uniqid ( rand() ) );
?>

You can attach a Word document if you specify:
<?php
$message
.= "Content-Type: application/msword; name=\"my attachment\"\n";
$message .= "Content-Transfer-Encoding: base64\n";
$message .= "Content-Disposition: attachment; filename=\"$theFile\"\n\n";
?>

When adding a file you must open it and read it with fopen and add the content to the message:
<?php
$path
= "whatever the path to the file is";
$fp = fopen($path, 'r');
do
//we loop until there is no data left
{
      
$data = fread($fp, 8192);
       if (
strlen($data) == 0) break;
      
$content .= $data;
     } while (
true);
$content_encode = chunk_split(base64_encode($content));
$message .= $content_encode . "\n";
$message .= "--" . $boundary . "\n";
?>

Add the needed headers and send!
<?php
$headers 
= "From: \"Me\"<me@here.com>\n";
$headers .= "MIME-Version: 1.0\n";
$headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"";
mail('myAddress@hotmail.com', 'Email with attachment from PHP', $message, $headers);
?>

Finally, if you add an image and want it displayed in your email, change the Content-Type from attachment to inline:

<?php
$message
.= "Content-Disposition: inline; filename=\"$theFile\"\n\n";
?>

Enjoy!
marcus at synchromedia dot co dot uk
18-Feb-2005 05:23
I've been helping a lot of people with scripting, and mail() is always a sticking point because no-one seems to be able to get the headers or MIME formatting right with their own code, mainly because you need to read all the RFCs and understand them in order to get it right. The simple answer is, don't bother trying: just use phpmailer instead: http://phpmailer.sourceforge.net/ it's a nice tidy PHP class that deals with multipart MIME construction, header and body encodings, and it has a built-in SMTP client too.

I really can't recommend it enough - it's worth pretending that the mail() function doesn't exist.

The PEAR mail package mentioned in here offers similar improvements in available sleep hours and hair retention.
Metin Savignano <ms201 at zipfly dot de>
04-Feb-2005 08:32
If you want to use the mail() function under *nix and Windows alike, I recommend using the little fake sendmail utility available under http://glob.com.au/sendmail/ (bsd license).

I tried it and it works great for me. I can use the very same PHP code on both the Linux server as well as my Windows test machine. It supports auth smtp.

Instructions: Download fake sendmail, unzip it into a directory of your choice, customize the sendmail.ini to your smtp server, set the sendmail path in your php.ini, and you're done.
maximo AT migliari DOT com
14-Jan-2005 02:58
If you are using Qmail and did the Life with Qmail installtion, verify that /var/qmail/bin/sendmail is chmodded to 755.

If its not, then the system will not be able to find the sendmail wrapper, even if /var/qmail/bin/sendmail IS in your path!

when I used the "which sendmail" command after having installed the qmail sendmail wrapper via "ln -s /var/qmail/bin/sendmail /sbin/sendmail" it returned no sendmail found!  I checked the permissions and it was set to no permissions for sendmail (very weird).

Anyway, php needs sendmail to be in the path for it to compile with mail() support.  Voilą! :)
Ivo Fokkema I.Fokkema att LUMC d0ttt nl
06-Sep-2004 04:03
We have a open source project that needed to be able to function on as many platforms and configurations as possible. Using '\n' as end-of-line for emailheaders would probably 'break' the email functionality on Windows and Mac platforms.

I have fixed this using the code below. Please note that since I don't have any access to a Mac server, this setup is not tested on a Mac, but should work.

if (strtoupper(substr(PHP_OS, 0, 3) == 'WIN')) {
       $s_eol = "\r\n";
} elseif (strtoupper(substr(PHP_OS, 0, 3) == 'MAC')) {
       $s_eol = "\r";
} else {
       $s_eol = "\n";
}

(Thanx to Eric Gach on http://www.phpbuilder.com/lists/php-windows/2003032/0057.php for the inspiration!)

Then construct your headers using

$s_headers = 'From: registrationform@example.org' . $s_eol;

Hope this helps anyone!!!

Ivo
php at richardneill dot org
12-Jul-2004 09:09
Postfix under Mandrake 10.0 also objects to \\r\\n. The result is that every email is double-spaced, and all attachments break. (it was OK in 9.1).  My (short-term) fix is this:

$message = str_replace("\r",'',$message);

This discussion may be relevant:
http://www.phpdiscuss.com/article.php?id=60615&group=php.bugs
wtmusic
13-Jun-2004 03:53
Beware of Mac "line feeds" (\r) in long text strings in the body of a message--may cause Sendmail to insert exclamation points after every 256 chars
def at speakeasy dot org
21-May-2004 09:11
The body of the message cannot, in some (many?) cases, contain "bare line feeds" -- i.e. just "\n".

See this: http://cr.yp.to/docs/smtplf.html
josh at sdfahrenheit dot com
15-Apr-2004 10:52
For anyone having problems with attached files coming through garbled, make sure you have magic_quotes_runtime set to Off in your php.ini - it adds funky escape chars to your attached data and garbles the attachment.

This was giving me all kinds of grief.
06-Apr-2004 08:36
If your system MTA is exim, you might find using it the following way gives you more control over the message that is sent. It uses batch SMTP rather than the hideous "-t" sendmail-like argument, and as a result allows the envelope and the headers to be specified seperately.

recipient, subject, body, [ [ [ headers ], sender ], helo]
bsmtp("recipient@address.com", "Subject", array("Line 1", "Line 2"), array(), "sender@address.com", "host.address.com);

OR

bsmtp(array("recipient1@address.com", "recipient2@address.com), "Subject", array("Line 1", "Line 2"), array(), "sender@addr$

<?php
function bsmtp($recipients, $subject, $body, $headers = array(), $sender= "<>"$helo = "")
{

      
$exim = "/usr/local/sbin/exim -bS";

       if (
$helo == "" )
       {
              
$helo = $_SERVER["HTTP_HOST"];
       }

       if ( !
$headers )
       {

               if (
is_array($recipients))
               {
                      
$c="To: ";
                       foreach (
$recipients as $r)
                       {
                              
$toheader .= $c . $r;
                              
$c = ", ";
                       }
               }
               else
               {
                      
$toheader = "To: " . $recipients;
               }

               if (
ereg("@", $sender))
               {
                      
$fromheader = "From: " . $sender;
               }
               else
               {
                      
$fromheader = "From: <MAILER-DAEMON@" . $_SERVER["HTTP_HOST"] . ">";
               }

              
$subj = "Subject: " . $subject;

              
$headers = array($toheader, $fromheader, $subj);

       }

      
$headers[] = "X-Mailer: Dave's better php mail function";

       print
"<PRE>";

      
$fd = popen($exim, "w");

      
fputs($fd, "HELO " . $helo . "\n");
      
fputs($fd, "MAIL FROM: " . $sender . "\n");
       if (
is_array($recipients))
       {
               foreach (
$recipients as $r)
               {
                      
fputs($fd, "RCPT TO: " . $r . "\n");
               }
       }
       else
       {
              
fputs($fd, "RCPT TO: " . $recipients . "\n");
       }

      
fputs($fd, "DATA\n");

       foreach (
$headers as $h )
       {
              
fputs($fd, $h . "\n");
       }

      
fputs($fd, "\n");

       foreach (
$body as $b )
       {
              
fputs($fd, $b . "\n");
       }

      
fputs($fd, "\n.\nQUIT\n");

      
sleep(1);

      
pclose($fd);
}

}
?>
roberto dot silva at mexicoshipping dot net
23-Jan-2004 07:16
If you can't use or don't understand how to use the sendmail program from linux, you can use a PEAR object to send mail.

<?
include("Mail.php");

$recipients = "mail_to@domain.mail";

$headers["From"]    = "mail_from@domain.mail";
$headers["To"]      = "mail_to@domain.mail";
$headers["Subject"] = "Test message";

$body = "TEST MESSAGE!!!";

$params["host"] = "smtp.server";
$params["port"] = "25";
$params["auth"] = true;
$params["username"] = "user";
$params["password"] = "password";

// Create the mail object using the Mail::factory method
$mail_object =& Mail::factory("smtp", $params);

$mail_object->send($recipients, $headers, $body);
?>

In my case, i use a smtp server that require authentication, and sendmail configuration is almost cryptic to me.

PEAR is already installed in PHP 4.0.3 , if not, you must go to pear.php.net and install it, in my case, I needed to add the Socket.php to the PEAR library.
aris AT riponce DOT com
19-Nov-2003 01:37
If you decide to send mail over an SMTP connection instead of using mail(), keep these hints in mind:

- Separate the header list from the message body with a single blank line. This way if the message body contains text that matches the headers you are safe.
- Apply the "hidden dot algirithm" to the body text. This simply means that if a line begins with a single "." just replace  it with two dots "..".

Example:

BEFORE:
-------------------
Subject: My message
Errors-To: me@mine.com
Subject: Lunch
Remember the following items:
item 1
.
.
.
Item 21
---------------------

AFTER:
---------------------
Subject: My message
Errors-To: me@mine.com

Subject: Lunch
Remember the following items:
item 1
..
..
..
Item 21
-----------------------
nes at techie dot com
26-Sep-2003 01:36
I've noticed some anti-spam email programs also deny delivery to mail that doesn't have a Message-ID.  Even though it is legal to do so, many domains will consider the email spam and drop it. 

Using sendmail on a win2k server, there is no Message-ID on some test mailings I've done.  The ones that are added were there due to the filtering software added it afterwards, at least that's what the spamheaders error code database says.
ronan dot minguy at wanadoo dot fr
20-Feb-2003 11:45
If you want to send an email in HTML with accent letters (for non-only-english speaking people) or the euro sign, put this in your header :
Content-Type: text/html; charset=iso-8859-15

Ronan
f dot touchard at laposte dot net
30-Jan-2003 10:46
***Encoding plain text as quoted-printable in MIME email***

If you don't want to install IMAP and use imap_8bit() to encode plain text or html message as quoted-printable
(friendly french special characters encoding :-) in MIME email, try this function.
I haven't fully tested it ( like with microtime with long mails). I send html message as 7-bit, so I didn't try yet with html.
If you have good html practise, you don't really need to encode html as quote-printable as it only uses 7-bit chars.
F.Touchard

function qp_encoding($Message) {
  
   /* Build (most polpular) Extended ASCII Char/Hex MAP (characters >127 & <255) */
   for ($i=0; $i<127; $i++) {
       $CharList[$i] = "/".chr($i+128)."/";
       $HexList[$i] = "=".strtoupper(bin2hex(chr($i+128)));
   }

   /* Encode equal sign & 8-bit characters as equal signs followed by their hexadecimal values */
   $Message = str_replace("=", "=3D", $Message);
   $Message = preg_replace($CharList, $HexList, $Message);

   /* Lines longer than 76 characters (size limit for quoted-printable Content-Transfer-Encoding)
       will be cut after character 75 and an equals sign is appended to these lines. */
   $MessageLines = split("\n", $Message);
   $Message_qp = "";
   while(list(, $Line) = each($MessageLines)) {
       if (strlen($Line) > 75) {
           $Pointer = 0;       
           while ($Pointer <= strlen($Line)) {
               $Offset = 0;
               if (preg_match("/^=(3D|([8-9A-F]{1}[0-9A-F]{1}))$/", substr($Line, ($Pointer+73), 3))) $Offset=-2;
               if (preg_match("/^=(3D|([8-9A-F]{1}[0-9A-F]{1}))$/", substr($Line, ($Pointer+74), 3))) $Offset=-1;
               $Message_qp.= substr($Line, $Pointer, (75+$Offset))."=\n";
               if ((strlen($Line) - ($Pointer+75)) <= 75) {               
                   $Message_qp.= substr($Line, ($Pointer+75+$Offset))."\n";
                   break 1;
               }
               $Pointer+= 75+$Offset;
           }
       } else {
           $Message_qp.= $Line."\n";
       }
   }       
   return $Message_qp;
}
rune at imptech dot net
21-Dec-2002 05:13
If your using Postfix for SMTP on FreeBSD you MUST end header lines with \n and not \r\n. I'm not sure if this is true of other platforms but this is definitely the case on my FreeBSD server.

-=- RuneImp
ImpTech - Web Design & Hosting
http://imptech.net
kieran dot huggins at rogers dot com
20-Nov-2002 05:24
Thanks Hilger - that will come in handy on my end.

Here's a great overview of the MIME spec from 1993:
http://www.mindspring.com/~mgrand/mime.html

Happy mailing! - Kieran
stevenlim at Edinburgh-Consulting dot com
06-Sep-2002 03:53
How to detect a bounce email

1. make sure the email you send out have the header
"Return-Path: detect-bounce@yourdomain.com\r\n",
&
"Return-Receipt-To: bounce@yourdomain.com\r\n"

2. setup this detect-bounce mail account at your mail server

3. redirect the incoming mail from this email account to your php script (check your mail server doc on how do this)

4. your php script will then be able to process the incoming email in whatever way you like, including to detect bounce mail message (use regexp search).

Note that the mail will be not be store after the mail server has redirect to your script.  If you want to store it, you need additional code in your script

Hope the above help

Steven Lim
IT Consultant (www.Edinburgh-Consulting.com)
11-Apr-2002 11:35
As noted above sendmail_from is only used on MS Windows, to change the default sender on unix you must add -f to sendmail_path. For example in a <VirtualHost> directive:
php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f webmaster@example.com"

would set the default return-path for mail from that virtual host.

<lzf_optimized_forezmlm_hash>
 Last updated: Thu, 19 May 2005
Copyright © 2001-2005 The PHP Group
All rights reserved.
This unofficial mirror is operated at: The Server Pages
Last updated: Thu May 19 18:35:34 2005 EDT