mail

(PHP 3, PHP 4, PHP 5)

mail -- Send mail

说明

bool mail ( string to, string subject, string message [, string additional_headers [, string additional_parameters]] )

Sends an email.

参数

to

Receiver, or receivers of the mail.

The formatting of this string must comply with RFC 2822. Some examples are:

user@example.com
user@example.com, anotheruser@example.com
User <user@example.com>
User <user@example.com>, Another User <anotheruser@example.com>

subject

Subject of the email to be sent.

注意

This must not contain any newline characters, or the mail may not be sent properly.

message

Message to be sent.

Each line should be separated with a LF (\n). Lines should not be larger than 70 characters.

注意

(Windows only) When PHP is talking to a SMTP server directly, if a full stop is found on the start of a line, it is removed. To counter-act this, replace these occurrences with a double dot.
<?php
$text
= str_replace("\n.", "\n..", $text);
?>

additional_headers (optional)

String to be inserted at the end of the email header.

This is typically used to add extra headers (From, Cc, and Bcc). Multiple extra headers should be separated with a CRLF (\r\n).

注: When sending mail, the mail must contain a From header. This can be set with the additional_headers parameter, or a default can be set in php.ini.

Failing to do this will result in an error message similar to Warning: mail(): "sendmail_from" not set in php.ini or custom "From:" header missing.

注: 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.

additional_parameters (optional)

The additional_parameters parameter can be used to pass an additional parameter to the program configured to use when sending mail using the sendmail_path configuration setting. For example, this can be used to set the envelope sender address when using sendmail with the -f sendmail option.

The user that the webserver runs as should be added as a trusted user to the sendmail configuration to prevent a 'X-Warning' header from being added to the message when the envelope sender (-f) is set using this method. For sendmail users, this file is /etc/mail/trusted-users.

返回值

Returns TRUE if the mail was successfully accepted for delivery, FALSE otherwise.

It is important to note that just because the mail was accepted for delivery, it does NOT mean the mail will actually reach the intended destination.

更新日志

版本说明
4.3.0 (Windows only) All custom headers (like From, Cc, Bcc and Date) are supported, and are not case-sensitive. (As custom headers are not interpreted by the MTA in the first place, but are parsed by PHP, PHP < 4.3 only supported the Cc header element and was case-sensitive).
4.2.3 The additional_parameters parameter is disabled in safe_mode and the mail() function will expose a warning message and return FALSE when used.
4.0.5 The additional_parameters parameter was added.

范例

例子 1. Sending mail.

Using mail() to send a simple email:

<?php
// The message
$message = "Line 1\nLine 2\nLine 3";

// In case any of our lines are larger than 70 characters, we should use wordwrap()
$message = wordwrap($message, 70);

// Send
mail('caffinated@example.com', 'My Subject', $message);
?>

例子 2. Sending mail with extra headers.

The addition of basic headers, telling the MUA the From and Reply-To addresses:

<?php
$to      
= 'nobody@example.com';
$subject = 'the subject';
$message = 'hello';
$headers = 'From: webmaster@example.com' . "\r\n" .
    
'Reply-To: webmaster@example.com' . "\r\n" .
    
'X-Mailer: PHP/' . phpversion();

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

例子 3. Sending mail with an additional command line parameter.

The additional_parameters parameter can be used to pass an additional parameter to the program configured to use when sending mail using the sendmail_path.

<?php
mail
('nobody@example.com', 'the subject', 'the message', null,
   
'-fwebmaster@example.com');
?>

例子 4. Sending HTML email

It is also possible to send HTML email with mail().

<?php
// multiple recipients
$to  = 'aidan@example.com' . ', '; // note the comma
$to .= 'wez@example.com';

// subject
$subject = 'Birthday Reminders for August';

// message
$message = '
<html>
<head>
  <title>Birthday Reminders for August</title>
</head>
<body>
  <p>Here are the birthdays upcoming in August!</p>
  <table>
    <tr>
      <th>Person</th><th>Day</th><th>Month</th><th>Year</th>
    </tr>
    <tr>
      <td>Joe</td><td>3rd</td><td>August</td><td>1970</td>
    </tr>
    <tr>
      <td>Sally</td><td>17th</td><td>August</td><td>1973</td>
    </tr>
  </table>
</body>
</html>
'
;

// To send HTML mail, the Content-type header must be set
$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

// Additional headers
$headers .= 'To: Mary <mary@example.com>, Kelly <kelly@example.com>' . "\r\n";
$headers .= 'From: Birthday Reminder <birthday@example.com>' . "\r\n";
$headers .= 'Cc: birthdayarchive@example.com' . "\r\n";
$headers .= 'Bcc: birthdaycheck@example.com' . "\r\n";

// Mail it
mail($to, $subject, $message, $headers);
?>

注: If intending to send HTML or otherwise Complex mails, it is recommended to use the PEAR package PEAR::Mail.

注释

注: The Windows implementation of mail() differs in many ways from the Unix implementation. First, it doesn't use a local binary for composing messages but only operates on direct sockets which means a MTA is needed listening on a network socket (which can either on the localhost or a remote machine).

Second, the custom headers like From:, Cc:, Bcc: and Date: are not interpreted by the MTA in the first place, but are parsed by PHP.

As such, the to parameter should not be an address in the form of "Something <someone@example.com>". The mail command may not parse this properly while talking with the MTA.

注: Email with attachments and special types of content (e.g. HTML) can be sent using this function. This is accomplished via MIME-encoding - for more information, see this Zend article or the PEAR Mime Classes.

注: It is worth noting that the mail() function is not suitable for larger volumes of email in a loop. This function opens and closes an SMTP socket for each email, which is not very efficient.

For the sending of large amounts of email, see the PEAR::Mail, and PEAR::Mail_Queue packages.

注: The following RFCs may be useful: RFC 1896, RFC 2045, RFC 2046, RFC 2047, RFC 2048, RFC 2049, and RFC 2822.


add a note add a note User Contributed Notes
rsjaffe at gmail dot com
24-May-2006 11:23
Oops. The backslashes got doubled. Each \\ should be \.
rsjaffe at gmail dot com
22-May-2006 05:10
Here's my way of detecting an attempt to hijack my mail form.

<?php #requires PHP 5 or greater
$request = array_map('trim',($_SERVER['REQUEST_METHOD'] == "POST") ? $_POST : $_GET) ;

//check for spam injection
$allfields = implode('',$request) ;
$nontext = $request ;
unset(
$nontext['message'] );
$nontextfields = implode ('',$nontext) ;
if ((
strpos ($nontextfields,"\\r")!==false) ||
   (
strpos ($nontextfields,"\\n")!==false) ||
   (
stripos ($allfields,"Content-Transfer-Encoding")!==false) ||
   (
stripos ($allfields,"MIME-Version")!==false) ||
   (
stripos ($allfields,"Content-Type")!==false) ||
   (
$request['checkfield']!=$check) ||
   (empty(
$_SERVER['HTTP_USER_AGENT']))) die('Incorrect request') ; //stop spammers ?>

First, I put the data into an array $request, then set up two strings: $allfields, which is just all fields concatenated, then $nontext, which excludes those fields in which \\r\\n is allowed (e.g., the message body). Any form field in which \\r\\n is allowed should be unset in the $nontext array before the second implode function (my message field is called 'message', so I unset that). I also include a hidden field in the form with a preset value ('checkfield', $check), so I can see if something is trying to alter all fields.

This is a combination of a lot of things mentioned in the messages below...
exel0n at hotmail dot com
05-Apr-2006 03:35
Based on LG83's, works for me...

function format($input) {
 $output = "=?ISO-8859-1?Q?";
 for ($x=0;$x<strlen($input);$x++) {
  $char = strtoupper(sprintf("%02s", dechex(ord($input[$x]))));
  $output .= "=".$char;
 }
 $output .= "?=";
 return($output);
}
steve at stevewinnington dot co dot uk
14-Mar-2006 12:24
To all you guys out there having problems with mail scripts throwing back this (and you know your scripts are right!!)...

Warning: mail() [function.mail]: "sendmail_from" not set in php.ini or custom "From:" header missing in:

I had started seeing this after moving some scripts from 4.3 servers to 5.

a dirty get around is using

ini_set ("sendmail_from","a.body@acompany.com");

to force the From header.

Not ideal but it works.
;)
Nimlhug
12-Mar-2006 02:41
As noted in other, well, notes; the "additional headers" parameter can be easily exploited, when doing things like:

<?php
  mail
( $_POST['to'], $_POST['subject'], $_POST['message'], 'Reply-to: '.$_POST['from']."\r\n" );
?>

An easy way of fixing this, is removing CRLFs from the header-strings, like so:

<?php
  $_POST
['from'] = str_replace( "\r\n", '', $_POST['from'] );
?>

This way, the extra data will be part of the previous header.
junaid at techni-serve dot com
08-Mar-2006 01:49
Note: on class "multipartmail".  Modify the function buildmessage with the following and it will work great.

function buildmessage(){
         $this->message = "This is a multipart message in mime format.\n";
         $cnt = count($this->parts);
         for($i=0; $i<$cnt; $i++){
           $this->message .= "--" . $this->boundary . "\n" .$this->parts[$i];
         }
       $this->message .= "--" . $this->boundary . "-- \n";
     }

Thank for all the help.
zorglub_olsen at hotmail dot com
06-Mar-2006 12:40
The function given by "lg83 at free dot fr" isn't working 100% reliably. There's apparently a problem with lastspace, but I don't fully understand the loop. The variables names don't help much either.

Example: encodeMimeSubject("Din giraf spiser Paradisbananer") gives "Din giraf spiser".
Mailer
05-Mar-2006 09:13
if you don't have access to the mail function or got a own smtp server you can use this class to send mails.
https://sourceforge.net/projects/p3mailer/
lg83 at free dot fr
24-Feb-2006 06:34
If you would like to send an email with non-ASCII characters in the subject (or any other header), this function will convert it into a 7 bit QP-encoded string that works with almost all mail clients (you are NOT allowed to send raw 8 bit data in a header, and even if you did there would be no way to know which charset was used).

This function takes a UTF-8 string in $s. If your PHP pages are in ISO-8859-1, just replace "=?UTF-8?Q?" with "=?ISO-8859-1?Q?" below.

<?php

function encodeMimeSubject($s) {
  
  
$lastspace=-1;
  
$r="";
  
$buff="";
  
  
$mode=1;
  
   for (
$i=0; $i<strlen($s); $i++) {
      
$c=substr($s,$i,1);
       if (
$mode==1) {
          
$n=ord($c);
           if (
$n & 128) {
              
$r.="=?UTF-8?Q?";
              
$i=$lastspace;
              
$mode=2;
           } else {
              
$buff.=$c;
               if (
$c==" ") {
                  
$r.=$buff;
                  
$buff="";
                  
$lastspace=$i;
               }
           }
       } else if (
$mode==2) {
          
$r.=qpchar($c);
       }
   }
   if (
$mode==2) $r.="?=";
  
   return
$r;
  
}

function
qpchar($c) {
  
$n=ord($c);
   if (
$c==" ") return "_";
   if (
$n>=48 && $n<=57) return $c;
   if (
$n>=65 && $n<=90) return $c;
   if (
$n>=97 && $n<=122) return $c;
   return
"=".($n<16 ? "0" : "").strtoupper(dechex($n));
  
}

?>
leonard_orb at future-data dot de
15-Feb-2006 05:51
Warning: It should be stated clearly that "additional_headers" (the 4th parameter)
will not only allow you to add customized mail headers.
If there is an empty line in it the mail headers will be terminated and
the mail body will start exactly at this point.

mail ("foo@bar.example", "Test", "Hi dude",
  "Bcc: someone_else@bar.example\r\n\r\nBuy V1a*ra now\r\n");

will send a mail to <foo@bar.example> and <someone_else@bar.example>
and advertise pills.

It will give spammers the chance to abuse your webserver as a spam server if you e.g.
happen not to check the values your form receives from the client and paste it
directly into "additional_headers".
linas.galvanauskas {eta} ntt . lt
13-Feb-2006 05:27
Hi,
I'm using phpmailer from http://phpmailer.sourceforge.net/

and I have no problems.
Good luck
Hossein
26-Jan-2006 01:46
Hello firends,
Good article about email:

http://www.sitepoint.com/article/advanced-email-php

With regards,Hossein
krisdover at hotmail dot com
21-Jan-2006 03:25
#  Description: Simple class using php mail function to construct and send mime multipart
#                emails (i.e. emails with attachments) and support content-id style
#                embedded images in html messages
#
#  Limitations: Uses the ubiquitously supported 7bit (i.e. no encoding) message encoding where as
#                qouted-printable is recommended for html messages. Does not ensure that message
#                line lengths do not exceed the 998 character limit specified by RFC 2822.
#
#  Usage Example:
#    $mulmail = new multipartmail("krisd@work.net", "destination@anywhere.com", "Some Subject");
#    $cid = $mulmail->addattachment("/var/www/html/img/pic.jpg", "image/jpg");
#    $mulmail->addmessage(
#      "<html>\n" .
#      "  <head>\n" .
#      "  </head>\n" .
#      "  <body>\n" .
#      "  This is text before<img src=\"cid:$cid\"> and after\n" .
#      "  </body>\n" .
#      "</html>\n", "text/html");
#    $mulmail->sendmail();

   class multipartmail{
     var $header;
     var $parts;
     var $message;
     var $subject;
     var $to_address;
     var $boundary;

     function multipartmail($dest, $src, $sub){
         $this->to_address = $dest;
         $this->subject = $sub;
         $this->parts = array("");
         $this->boundary = "------------" . md5(uniqid(time()));
         $this->header = "From: $src\r\n" .
                         "MIME-Version: 1.0\r\n" .
                         "Content-Type: multipart/related;\n" .
                         " boundary=\"" . $this->boundary . "\"\r\n" .
                         "X-Mailer: PHP/" . phpversion();
     }

     function addmessage($msg = "", $ctype = "text/plain"){
         $this->parts[0] = "Content-Type: $ctype; charset=ISO-8859-1\r\n" .
                           "Content-Transfer-Encoding: 7bit\r\n" .
                           "\n" . $msg;
                           //chunk_split($msg, 68, "\n");
     }

     function addattachment($file, $ctype){
         $fname = substr(strrchr($file, "/"), 1);
         $data = file_get_contents($file);
         $i = count($this->parts);
         $content_id = "part$i." . sprintf("%09d", crc32($fname)) . strrchr($this->to_address, "@");
         $this->parts[$i] = "Content-Type: $ctype; name=\"$fname\"\r\n" .
                           "Content-Transfer-Encoding: base64\r\n" .
                           "Content-ID: <$content_id>\r\n" .
                           "Content-Disposition: inline;\n" .
                           " filename=\"$fname\"\r\n" .
                           "\n" .
                           chunk_split( base64_encode($data), 68, "\n");
         return $content_id;
     }

     function buildmessage(){
         $this->message = "This is a multipart message in mime format.\n";
         $cnt = count($this->parts);
         for($i=0; $i<$cnt; $i++){
           $this->message .= "--" . $this->boundary . "\n" .
                             $this->parts[$i];
         }
     }

     /* to get the message body as a string */
     function getmessage(){
         $this->buildmessage();
         return $this->message;
     }

     function sendmail(){
         $this->buildmessage();
         mail($this->to_address, $this->subject, $this->message, $this->header);
     }
   }

?>
# inspired by code found here. thanks to all
corretge at gmail dot com
13-Dec-2005 05:19
A way to keep out spamers if in your form or script tell about From e-mail, and put it in the Header is (if the variable name is email):

$emiliu = $_REQUEST['email'];
if ( preg_match ( "/^[-\w.]+@([A-z0-9][-A-z0-9]+\.)+[A-z]{2,4}$/", $emiliu) )
{
   OK  ... bla... bla.... bla

   $mailHead = "From: " . $_REQUEST['email'];
   mail($mailTO, $mailSbj, $mailBodyC . $mailBody, $mailHead);

}
else
{
  BAD HEADER
}
php at nioubi dot com
15-Nov-2005 07:43
For me, WinXP, EasyPHP 1.8.0.1, sending a mail with the headers lines separated by : \r\n
$headers  = "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset=iso-8859-1\r\n";

When I put the script online, and call it in order to send mail,
the html is displayed in the mail client (tested Outlook Express and Thunderbird) when you want to read the message sent by php. Some of the headers are considered like text (but it works when sent from local).

Solution : not use \r\n but only \n.
doom_blaster at hotmail dot com
12-Oct-2005 09:47
OK you gave good exemples but none look good with Lotus Notes 6.X. I found some exelent code compatible with Notes and others, the detailed solution is here :http://archivist.incutio.com/viewlist/css-discuss/37970

I have cleaned Rowan's text, this is my working code :

$boundary = md5(uniqid(time()));

$headers  = 'From: ' . $from . "\n";
$headers .= 'To: ' . $to . "\n";
$headers .= 'Return-Path: ' . $from . "\n";
$headers .= 'MIME-Version: 1.0' ."\n";
$headers .= 'Content-Type: multipart/alternative; boundary="' . $boundary . '"' . "\n\n";
$headers .= $body_simple . "\n";
$headers .= '--' . $boundary . "\n";
$headers .= 'Content-Type: text/plain; charset=ISO-8859-1' ."\n";
$headers .= 'Content-Transfer-Encoding: 8bit'. "\n\n";
$headers .= $body_plain . "\n";
$headers .= '--' . $boundary . "\n";
$headers .= 'Content-Type: text/HTML; charset=ISO-8859-1' ."\n";
$headers .= 'Content-Transfer-Encoding: 8bit'. "\n\n";
$headers .= $body_html . "\n";
$headers .= '--' . $boundary . "--\n";

$mailOk=mail('', $subject,'', $headers);

(Tested from Linux PHP4 to STMP Lotus Notes and Notes Client 6.5.1 & 5.? , it works with hotmail too, I didn't test other client)

by DitLePorc
GwarDrazul
15-Sep-2005 07:01
The article mentioned below is quite good to understand the problem of header injection. However, it suggests the following as a solution: look for "\n" and "\r" inside your user input fields (especially in those used for the $header param) and, if found reject the mail.

Allthough this will probably work I still believe it is better to have a "white list" of allowed characters instead of a "black list" with forbidden characters.

Example:
If you want a user to enter his name, then allow characters only!
If you want a user to enter his email adress, then check if the entry is a valid email adress.

Doing so might automatically solve problems which you didn't think of when you created the "black list". For SMTP headers colons are needed. If you check for a valid email adress the hacker won't be able to enter colons inside that form field.

I suggest using regular expressions for those checks.

For more information about regular expressions see:
http://www.regular-expressions.info/
Alan Hogan +PHP at pixels and pages ,com
04-Sep-2005 01:46
Header injection is a very real, common threat in which an attacker uses your mail form to send mail to whomever he chooses!  I've been hit, myself, and on a website with relatively little traffic!  Read more about it here:

http://securephp.damonkohler.com/index.php/Email_Injection
jfonseca at matarese dot com
26-Jul-2005 08:33
This is NOT PHP-specific but worth mentioning on the mail() page.

Watch out for sendmail command injection on your pages which call the mail() function.

How it works: the attacker will inject SMTP into your form unless you make it real clear where the header ends. Most people simply don't add a header or a \r\n\r\n sequence to their mail header forms.

Example : a new BCC: field can be injected so that your form can be used to deliver mail to any valid address the attacker chooses.

Since the httpd server host is a trusted host your MX will probably relay without asking any questions.

Be careful with any function that accepts user input.

Hope this helps.
a dot hari at softprosys dot com
26-Jul-2005 01:47
Guido, the same you can do like this.

while ($emailadresses = mysql_fetch_array($query, MYSQL_ASSOC)) {
   foreach ($emailadresses as $oneMailadres) {
       $recepientsArr[] = "$oneMailadres"; //build up the recepients array
   }
}
/* THIS IS NOT REQUIRED
// this is the tricky part: mail() will not sent to all the emailadresses, if you let your string end with ', ', so I used substr() to remove the last two characters from the string (comma and space).
$recepients = substr($recepients, 0, -2);
*/

//Instead...do this.
$recepients = implode(",", $recepientsArr[]);
//actual sending
mail($recepients, $subject, $mailbody, "From: $senderAddress");
Guido
20-Jul-2005 05:21
When you want to sent mail to emailadresses that you've got stored in a database, one can use this code (at least it's been usefull to me ;):

// fetch adresses from database
while ($emailadresses = mysql_fetch_array($query, MYSQL_ASSOC)) {
   foreach ($emailadresses as $oneMailadres) {
       $recepients .= "$oneMailadres"; //build up the recepient string
       $recepients = $recepients . ", ";
   }
}
// this is the tricky part: mail() will not sent to all the emailadresses, if you let your string end with ', ', so I used substr() to remove the last two characters from the string (comma and space).
$recepients = substr($recepients, 0, -2);
//actual sending
mail($recepients, $subject, $mailbody, "From: $senderAddress");
gregBOGUS at BOGUSlorriman dot com
21-Jun-2005 06:02
In the posting "gregBOGUS at BOGUSlorriman dot com 6th april 2005" I claimed that redirecting an email, via the mail() function, to a different email address was as simple as copying over the unmodified headers of the originally recieved email (which would, of course, include the original "To:" field).

However it seems that this works for a Xampp install (http://www.apachefriends.org/en/xampp.html) with Mercury as the mail agent, but doesn't work on my webhost without first removing the old "To:" field, and perhaps other header modifications. Therefore it looks like it would be safest to strip any header lines that shouldn't be there. <sigh>

http://www.lorriman.com
tarlrules at users dot sourceforge dot net
16-Jun-2005 02:26
You may also want to take a look at email() a mail() clone with built in MTA. This is particually useful if you webhost does has dissable access to mail.

email() is avaliable here: http://poss.sourceforge.net/email along with a php.net style function referance http://poss.sf.net/email/index.php?type=Documentation&page=email

Hope that help someone.

Jason
macronesia at macronesia dot net
16-Jun-2005 12:25
After doing some conductive testing, I have found that the popular GMail E-Mail system throws a 550 error when you send mail with the 'to' argument in the "User <user@example.com>" format.

I spent about twenty minutes bothering with it, and then just added the "user@example" argument, which works fine.

Just a note to save other people time. It might, however, work with sending E-Mail to people in my original format in a header.
javier at zincro dot com
01-Jun-2005 12:48
This might be something obvious, but it gave me a lot of headache to find out:

If you use an ascii char#0 in the "string mensaje" parameter, it will truncate the message till that point, (this happened to me sending a message read from a file)

For example:
<?
$hs_email
="blabla@blabla.com";
$hs_asunto="a message for you";

$hs_contenido="beginofcontent_";
$hs_contenido.=chr(0);
$hs_contenido.="_endofcontent";

mail($hs_email,$hs_asunto,$hs_contenido);
?>

Will result in an email that only contains the string:

beginofcontent_

Anyway, just in case it can save someone some time...
msheldon at desertraven dot com
15-May-2005 03:09
Just a comment on some of the examples, and as a note for those who may be unaware. The SMTP RFC 822 is VERY explicit in stating that \r\n is the ONLY acceptable line break format in the headers, though is a little vague about the message body. While many MTAs will deal with just \n, I've run accross plenty of them that will exhibit "interesting" behaviours when this happens. Those MTAs that are strict in compliance will definitely break when header lines are terminated with only \n. They will also most likely break if the body of the message contains more than 1000 consecutive characters without a \r\n.*

Note that RFC 821 is a little more clear in defining:
"line
     A a sequence of ASCII characters ending with a <CRLF>."

RFC 821 makes no distinction between header lines and message body lines, since both are actually transmitted during the DATA phase.

Bottom line, best practice is to be sure to convert any bare \n characters in the message to \r\n.

* "The maximum total length of a text line including the <CRLF> is 1000 characters" (RFC 821)
v152535 at mail dot ru (Vladimir)
09-May-2005 09:03
Good Example from http://docs.com.ru/php_3.php :
Send file.zip on 333@mail.ru .
File file.zip  inheres beside this php:

<?php

class mime_mail {
var
$parts;
var
$to;
var
$from;
var
$headers;
var
$subject;
var
$body;

// 
function mime_mail() {
 
$this->parts = array();
 
$this->to "";
 
$this->from "";
 
$this->subject "";
 
$this->body "";
 
$this->headers "";
}

//       
function add_attachment($message, $name = "", $ctype = "application/octet-stream") {
 
$this->parts [] = array (
 
"ctype" => $ctype,
 
"message" => $message,
 
"encode" => $encode,
 
"name" => $name
 
);
}

//  (multipart)
function build_message($part) {
 
$message = $part["message"];
 
$message = chunk_split(base64_encode($message));
 
$encoding = "base64";
 return
"Content-Type: ".$part["ctype"].($part["name"]? "; name = \"".$part["name"]."\"" : "")."\nContent-Transfer-Encoding: $encoding\n\n$message\n";
}

function
build_multipart() {
 
$boundary = "b".md5(uniqid(time()));
 
$multipart = "Content-Type: multipart/mixed; boundary = $boundary\n\nThis is a MIME encoded message.\n\n--$boundary";
 for(
$i = sizeof($this->parts)-1; $i>=0; $i--) $multipart .= "\n".$this->build_message($this->parts[$i]). "--$boundary";
 return
$multipart.=  "--\n";
}

//  ,   
function send() {
 
$mime = "";
 if (!empty(
$this->from)) $mime .= "From: ".$this->from. "\n";
 if (!empty(
$this->headers)) $mime .= $this->headers. "\n";
 if (!empty(
$this->body)) $this->add_attachment($this->body, "", "text/plain"); 
 
$mime .= "MIME-Version: 1.0\n".$this->build_multipart();
 
mail($this->to, $this->subject, "", $mime);
}
}

$attachment = fread(fopen("file.zip", "r"), filesize("file.zip"));
$mail = new mime_mail();
$mail->from = "my@e-mail.com";
$mail->headers = "Errors-To: [EMAIL=my@e-mail.com]my@e-mail.com[/EMAIL]";
$mail->to = "333@mail.ru";
$mail->subject = "PHP atachment";
$mail->body = "Get your file!";
$mail->add_attachment("$attachment", "file.zip", "Content-Transfer-Encoding: base64 /9j/4AAQSkZJRgABAgEASABIAAD/7QT+UGhvdG9zaG");
$mail->send();

?>
daniel at tamm-tamm dot de
01-May-2005 10:06
In the code of gordon at kanazawa-gu dot ac dot jp, long subjects become corrupted when using utf-8 encoding because of the length parameter. The following version works even with utf-8:
<?php
// ...
// determine length of encoded text within chunks
// and ensure length is even
$length = 75 - strlen($start) - strlen($end);
$length = floor($length/4) * 4;
// ...
?>
marcus at synchromedia dot co dot uk
27-Apr-2005 01:06
The docs are slightly confusing by talking about the additional_paramaters paramater as being able to contain 'an additional parameter' in the singular.

The additional_parameters parameter is simply a string that gets concatenated onto the command passed to sendmail, so you can put as many params in there as you like, for example '-fme@example.com -R hdrs'
jonte at macnytt dot com
25-Apr-2005 07:16
Users of Mac OS X Server need to activate SMTP part of the Mailserver before this is working.

Also note that if the ISP has blocked port 25 outgoing, you run into problems. You can find more info about this in the SMTP server log in Server Admin application if you run OSX Server.
Jeffrey
20-Apr-2005 10:18
<?php
class clsMail
{
   var
$to;
   var
$from;
   var
$cc;
   var
$bcc;
   var
$subject;
   var
$message;
   var
$contentType;
  
   function
clsMail() //init
  
{
      
$this->to        =    "";
      
$this->from    =    "";
      
$this->cc    =    "";
      
$this->bcc    =    "";
      
$this->subject    =    "";
      
$this->message    =    "";
      
$this->contentType = "html"; // text, html
  
}
  
   function
isemail($email)
   {
      
// regx to test for valid e-mail adres
      
$regex = '^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]{2,})+$';
       if (
eregi($regex, $email)) return true;
       else return
false;
   }
  
   function
send()
   {
      
// check if e-mail adresses are valid.
      
if (!clsMail::isemail($this->to)) die('ERROR: Invalid To e-mail adres');
       if (!
clsMail::isemail($this->from)) die('ERROR: Invalid From e-mail adres');
       if (!
clsMail::isemail($this->cc) && !$this->cc=="") die('ERROR: Invalid CC e-mail adres');
       if (!
clsMail::isemail($this->bcc) && !$this->bcc=="") die('ERROR: Invalid BCC e-mail adres');
      
      
// To send HTML mail, you can set the Content-type header. html is the default
      
$headers  = "MIME-Version: 1.0\r\n";
       if (
$this->contentType=="html") $headers .= "Content-type: text/html; charset=iso-8859-1\r\n";
       else
$headers .= "Content-type: text/plain; charset=us-ascii\r\n";
      
      
// additional headers  for From, Cc and Bcc
      
$headers .= "From: ".$this->from."\r\n";
       if (!
$this->cc==""$headers .= "Cc: ".$this->cc."\r\n";
       if (!
$this->bcc=="") $headers .= "Bcc: ".$this->bcc."\r\n";
      
      
// send the e-mail
      
return mail($this->to, $this->subject, $this->message, $headers);
   }
  
}

// example how te use the mail class
$mail = new clsMail();
$mail->to="someone@domain.com";
$mail->from="me@domain.com";
$mail->subject="My Subject";
$mail->message="My Message body";
echo
$mail->send(); // returns true or false at failure
?>
19-Apr-2005 03:20
A co-worker of mine had a problem where she needed to have a backslash in the header. Basically, the name of the company has a couple of backslashes in it. However, when the recipient was receiving the email, the "From:" part had the backslashes removed. We got it to work but placing three backslashes whenever we wanted one to show up. I'd assume that the mail server was modifying the headers and this is not really an issue with php. Anyway, thought this might help someone.
fabrice dot potron at gmail dot com
14-Apr-2005 05:47
with php4.xx
/* destinataire */
$to  = "Mary <mary@example.com>" // ok

with php5 :
/* destinataire */
$to  = "Mary <mary@example.com>" // NO mail return true but the mail isn't start (i don't speak english) :(
$to  = "mary@example.com" // ok :)
gregBOGUS at BOGUSlorriman dot com
06-Apr-2005 08:05
A comfortable way to redirect an email :

(Obviously there are other ways to redirect, but this could save someone a lot of hassle. )

If all you want to do is redirect an email and you want to do it from the comfort of the mail() and imap_X() functions then surprisingly mail() will successfully send an email to your chosen destination with the contents intact (text/mime/multipart whatever) by just dumping the result of imap_fetchheader into the header parameter and dumping imap_body into the body parameter. For example :

<?php

$header
=imap_header($mbox,1);

mail('somechap@somewhere.com',$header->Subject,imap_body($mbox,1), imap_fetchheader($mbox,1));

?>

Notice that you still have to transfer the subject line manually using imap_header.

One note, however, is that it may be possible on particular platforms that the header info might have had its CRLFs mangled and so this technique might need adjustment if you are unlucky.

Also note that this is a somewhat surprising method, and one might be (wisely) circumspect about using a technique that could be broken by an unfortunate updating of mail(). However I don't believe this is a significant concern as the mail() function is very simple in what it offers, such that the likelyhood of broken code is about as minimal as can be expected. However apps that need to be industrially strong should probably not use this technique.

Greg

http://www.lorriman.com
gardan at gmx dot de
31-Mar-2005 10:41
An addition to the comment by gordon at kanazawa-gu dot ac dot jp:

In his function encode() he has the following line:

$length = floor($length/2) * 2;

which should actually be

$length = $length - ($length % 4);

This means: $length should not be even, but divisible by 4. The reason is that in base64-encoding 3 8-bit-chars are represented by 4 6-bit-chars. These 4 chars must not be split between two encoded words, according to RFC-2047.
benles at bldigital dot com
21-Mar-2005 01:47
I get a 550 error when using mail() with this To format:

User <user@example.com>

When it's changed to just the bare email, it works fine. Just FYI that some mail servers may behave this way.
php dot net at schrecktech dot com
03-Mar-2005 08:07
When sending MIME email make sure you follow the documentation with the "70" characters per line...you may end up with missing characters...and that is really hard to track down...
Ian Chilton
21-Feb-2005 08:52
\r\n after each header doesn't seem to work in some mailers (eg: Gmail) - \n seems to work ok.
grey at greywyvern dot moc
19-Feb-2005 04:47
When including your own custom headers try not to include a trailing \r\n at the end of the last header.  Leaving the \r\n causes an extra line-feed at the beginning of the message body, so your message will start on the second line.
Sven Riedel
10-Jul-2004 09:22
mail() requires /bin/sh to exist in Unix environments, next to a mail delivery program. This is very relevant when setting up apache in a chroot environment. Unfortunately this isn't anywhere in the documentation and took me several months to figure out.
nospam at mingo dot ath dot cx
09-May-2004 09:55
If you're using a linux server using Postfix, and your server hasn't the host name set to a valid name (because it's behind a firewall in an intranet), it's possible that when sending mails using the mail function, some mail servers reject them. This is because they can't check the return path header. If you want to change the Return-Path used by sendmail init the php.ini and edit the sendmail_path variable to this:

sendmail_path = "sendmail -t -i -F webmaster@yoursite.com -f webmaster@yoursite.com"
Paul
25-Feb-2004 06:51
My mime multipart/alternative messages were going ok, until I switched to qmail with php .. after years of painfull searching, I came across this on the Life With Qmail 'Gotchas' section:

G.11. Carriage Return/Linefeed (CRLF) line breaks don't work

qmail-inject and other local injection mechanisms like sendmail don't work right when messages are injected with DOS-style carriage return/linefeed (CRLF) line breaks. Unlike Sendmail, qmail requires locally-injected messages to use Unix newlines (LF only). This is a common problem with PHP scripts.

So now, I can go back to sending emails with text AND html components :)
gordon at kanazawa-gu dot ac dot jp
29-Dec-2002 10:04
If your server doesn't have mb_send_mail() enabled but you want to use non-ascii (multi-byte) chars in an email's subject or name headers, you can use something like the following:

<?php
$charset
= "iso-2202-jp"; // japanese
$to = encode("japanese name 01", $charset) . " <to@email.com>";
$from = encode("japanese name 02", $charset) . " <from@email.com>";
$subject = encode("japanese text");
$message = "does not need to be encoded";
mail($to, $subject, $message, $from);

function
encode($in_str, $charset) {
  
$out_str = $in_str;
   if (
$out_str && $charset) {

      
// define start delimimter, end delimiter and spacer
      
$end = "?=";
      
$start = "=?" . $charset . "?B?";
      
$spacer = $end . "\r\n " . $start;

      
// determine length of encoded text within chunks
       // and ensure length is even
      
$length = 75 - strlen($start) - strlen($end);
      
$length = floor($length/2) * 2;

      
// encode the string and split it into chunks
       // with spacers after each chunk
      
$out_str = base64_encode($out_str);
      
$out_str = chunk_split($out_str, $length, $spacer);

      
// remove trailing spacer and
       // add start and end delimiters
      
$spacer = preg_quote($spacer);
      
$out_str = preg_replace("/" . $spacer . "$/", "", $out_str);
      
$out_str = $start . $out_str . $end;
   }
   return
$out_str;
}
// for details on Message Header Extensions
// for Non-ASCII Text see ...
// http://www.faqs.org/rfcs/rfc2047.html

?>