PHP
downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

Mailparse> <ezmlm_hash
Last updated: Fri, 30 Jan 2009

view this page in

mail

(PHP 4, PHP 5)

mail메일을 보냅니다

설명

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

이메일을 보냅니다.

인수

to

메일 수신자.

이 문자열의 형식은 » RFC 2822에 적합해야 합니다. 예를 들면:

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

subject

보낼 이메일의 제목.

Caution

제목은 » RFC 2047을 만족해야 합니다.

message

보내질 메세지.

각 줄은 LF(\n)로 구분되어야 합니다. 한 줄은 70 문자를 넘을 수 없습니다.

Caution

(윈도우만) PHP가 SMTP 서버와 직접 통신할 때, 줄 시작의 마침표가 제거됩니다. 이를 방지하려면, 이런 마침표를 2개로 교체할 수 있습니다.

<?php
$text 
str_replace("\n.""\n.."$text);
?>

additional_headers (선택적)

이메일 헤더 마지막에 추가될 문자열.

헤더를 추가하기 위해서 사용됩니다. (From, Cc, Bcc) 여러 추가 헤더는 CRLF(\r\n)로 구분해야 합니다.

Note: 메일을 보낼 때, From 헤더를 포함해야 합니다. 이는 additional_headers 인수를 통하여 설정하거나, 기본값을 php.ini에 설정할 수 있습니다.
이 작업을 하지 않으면 다음과 비슷한 오류 메세지가 출력됩니다. Warning: mail(): "sendmail_from" not set in php.ini or custom "From:" header missing. 윈도우에서 From 헤더는 Return-Path도 설정합니다.

Note: 메세지가 전달되지 않으면, LF(\n)만 사용해 보십시오. 몇몇 질 나쁜 유닉스 메일 전송 에이전트는 자동으로 LF를 CRLF로 교체합니다. (이 경우 CRLF를 쓰면 CR이 두번 들어가게 됩니다) 이는 최후 수단이여야 하며, » RFC 2822에 적합하지 않습니다.

additional_parameters

sendmail_path 설정을 사용하여 메을을 보낼 때, additional_parameters 인수를 사용하여 추가적인 인수를 전달할 수 있습니다. 예를 들면, -f sendmail 옵션을 사용하여 봉투 전송 주소를 넣을 수 있습니다.

웹 서버를 운영하는 사용자는 sendmail 설정에 신뢰하는 사용자를 추가하여, 이 방식(-f)으로 봉투 전송 주소를 넣을 때 'X-Warning' 헤더 추가를 막을 수 있습니다. sendmail 사용자라면, 이 파일은 /etc/mail/trusted-users입니다.

반환값

메일이 성공적으로 전송이 허용되었을 때는 TRUE, 그 외에는 FALSE를 반환합니다.

이는 메일 전송이 허용 되었을 뿐, 원하는 목적지에 도착한 것을 의미하는 것이 아니라는 점에 주의하십시오.

변경점

버전 설명
4.3.0 (윈도우만) 모든 사용자 헤더(From, Cc, Bcc, Date 등)를 지원하고, 대소문자를 구분하지 않습니다. (사용자 헤더를 직접 MTA에 보내지 않고 먼저 PHP에서 처리함으로써, PHP < 4.3만 Cc 헤더 요소를 지원하고, 대소문자 구분을 하지 않습니다)
4.2.3 safe_mode에서 additional_parameters 인수를 쓸 수 없고, mail() 함수를 이 인수와 함께 사용하면 경고 문구를 출력하고 FALSE를 반환합니다.
4.0.5 additional_parameters 인수가 추가되었습니다.

예제

Example #1 메일 보내기.

간단한 이메일을 보내기 위해 mail() 사용하기:

<?php
// 메세지
$message "Line 1\nLine 2\nLine 3";

// 한 줄이 70 문자를 넘어갈 때를 위하여, wordwrap()을 사용해야 합니다.
$message wordwrap($message70);

// 전송
mail('caffeinated@example.com''My Subject'$message);
?>

Example #2 추가 헤더와 함께 메일 보내기

기본 헤더를 추가하여, MUA에게 From과 Reply-To 주소를 알려줍니다:

<?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);
?>

Example #3 추가적인 명령줄 인수와 함께 메일 전송하기.

additional_parameters 인수는 메일을 보낼 때 사용하는 sendmail_path 설정에 있는 프로그램에 추가 인수를 넘깁니다.

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

Example #4 HTML 이메일 보내기

mail()로 HTML 이메일을 보낼 수 있습니다.

<?php
/* 다중 수신자 */
$to  'aidan@example.com' ', ' // 콤마인 것에 주의.
$to .= 'wez@example.com';

// 제목
$subject 'Birthday Reminders for August';

// 메세지
$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>
'
;

// HTML 메일을 보내려면, Content-type 헤더를 설정해야 합니다.
$headers  'MIME-Version: 1.0' "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' "\r\n";

// 추가 헤더
$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($to$subject$message$headers);
?>

Note: HTML이나 다른 복잡한 메일을 보낼 때는, PEAR 패키지 » PEAR::Mail_Mime 사용을 권장합니다.

주의

Note: 윈도우에서 mail()은 유닉스에서와는 많은 점이 다릅니다. 첫번째로, 메세지 작성에 로컬 바이너리를 사용하지 않고 직접 소켓으로 작동합니다. 즉, MTA 네트워크 소켓(로컬호스트건 원격이건)이 열려 있어야 합니다.
두번째로, From:, Cc:, Bcc:, Date: 등의 사용자 헤더는 MTA에 직접 해석되지 않으며, PHP에서 처리합니다.
그러므로, to 인수는 "Something <someone@example.com>" 형태로 주어져서는 안됩니다. mail 명령은 MTA와 통신할 때 이를 정상적으로 처리하지 못할 수 있습니다.

Note: 첨부 파일과 특수한 내용 형식(예, HTML)을 가진 이메일을 이 함수로 보낼 수 있습니다. 이는 MIME-인코딩으로 이루어 집니다 - 자세한 사항은 » 젠드 글이나 » PEAR Mime 클래스를 참조하십시오.

Note: mail() 함수는 루프를 돌며 많은 양의 이메일을 처리하기엔 적합하지 않습니다. 이 함수는 각 이메일에 대하여 SMTP 소켓을 열고 닫으며, 매우 비효율적입니다.
많은 양의 이메일을 보내려면, » PEAR::Mail» PEAR::Mail_Queue 패키지를 알아보십시오.

Note: 다음 RFC가 유용합니다: » RFC 1896, » RFC 2045, » RFC 2046, » RFC 2047, » RFC 2048, » RFC 2049, » RFC 2822.

참고



Mailparse> <ezmlm_hash
Last updated: Fri, 30 Jan 2009
 
add a note add a note User Contributed Notes
mail
deepakkallungal at gmail dot com
23-Jan-2009 09:34
For solving japanese subject in php mail.

we had a problem was when we give shift-jis encoded test for subject in mail, the mail received  displayed as "BQ Tech\ Ý t H [" in subject where the content in the mail was showing correctly.
we solved it by using this code.

$subject =iconv( "Shift_JIS","EUC-JP", "BQ Tech申込みフォーム");

we can convert like this for japanese encoding not working correctly for japanese text.
orjtor
19-Jan-2009 10:17
This is my solution of problems with Windows Mail on Vista. I got some of the headers in the mail body as plain text. When I removed '\r' and left just '\n' at the end of the two last lines of header it worked. This error didn't show up in my yahoo mail.
<?php
    $body
= "<html>\n";
   
$body .= "<body style=\"font-family:Verdana, Verdana, Geneva, sans-serif; font-size:12px; color:#666666;\">\n";
   
$body = $message;
   
$body .= "</body>\n";
   
$body .= "</html>\n";
   
   
$headers  = "From: My site<noreply@my_site.com>\r\n";
   
$headers .= "Reply-To: info@my_site.com\r\n";
   
$headers .= "Return-Path: info@my_site.com\r\n";
   
$headers .= "X-Mailer: Drupal\n";
   
$headers .= 'MIME-Version: 1.0' . "\n";
   
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
   
    return
mail($recipient, $subject, $message, $headers);
?>
tyagi dot akhil at gmail dot com
04-Jan-2009 04:29
To send XML content in mail use this

Content-Type: text/xml

instead of Content-Type: text/html
Tim Johannessen
15-Dec-2008 04:59
I tried the example provided by [hn at nesland dot net] but it didn't quite work, as the error:
Fatal error: Cannot redeclare mail()
was encountered.

Also, the runkit_function_rename() caused apache to exit with Segmentation fault (11)

This works like a charm:

<?PHP
@dl("runkit.so");
@
runkit_function_copy("mail", "__org_mail");
@
runkit_function_remove("mail");
@
runkit_function_copy("__new_mail", "mail");
@
runkit_function_remove("__new_mail");

function
__new_mail($to, $subject, $message, $additional_headers = null, $additional_parameters = null) {
  
/* do your own mail function checks here */
  
return __org_mail($to, $subject, $message, $additional_headers, $additional_parameters);
}
?>

Atleast it worked for me, stripping newlines from $to, $subject, removing unwanted headers from $additional_headers and adding new headers to $additional_headers for debugging - this way I'll be able to track the origin of the mail using the headers.

You'll need enable_dl = On in your php.ini and also runkit.internal_override = "1"

I wanted to remove the execution of __org_mail(), so I tried to add this to disable_functions in php.ini but that didn't seem to work, so be aware that the original function can still be executed, and found by using get_defined_functions().
php at ontheroad dot net dot nz
04-Nov-2008 07:00
Another possible cause for the "501 5.5.4 Invalid Address" type errors when sending mail from Windows is specifying BCC or CC parameters with no value.
devnull at div dot org
16-Oct-2008 04:29
I just had a little run-in with the postfix developers over at postfix-users about this issue.

http://tech.groups.yahoo.com/group/postfix-users/message/244799

Quote:Wietse Venema:
>> Specifically, Postfix accepts local submissions in UNIX format
>> (LF) or MSDOS format (CRLF) format BUT YOU MIST NOT MIX FORMATS.
>
> So how does postfix determine what format you are using?
> Is there a way to explicitly tell it what to expect?
>
Postfix looks at the first input line. There currently is no
way to override this, so your best bet is to use the same line
terminator consistently (having a first line with CRLF might
work "best" for hybrid mail, but that behavior is not promised).

The current behavior originates from the time when binary transparency
was considered a good thing.
--

There seemed to me to be a marked hostility towards the idea of
trying to be helpful about this, but on the other hand I got the
impression they might not be hostile if someone offered a patch for
a SENDMAIL_EOF_COMPAT_MODE or similar.

Personally I am not much good at C, but the challenge is hereby issued :)
molotster on google mail com
13-Oct-2008 11:03
Note, that single line should not contain more than 78 character, but is not allowed to contain more than 998 characters.

The possible consequences are:
Over 78 - clients are allowed to display the message in a "harder to read" way.
Over 998 - clients and servers are allowed to drop the message or cause any buffer-limit error.

See:
http://www.faqs.org/rfcs/rfc2822 part 2.1.1.
duminda
17-Sep-2008 11:44
<?PHP
$title
=$_POST['title'];
$name=$_POST['name'];
$email=$_POST['email'];
$telephone=$_POST['telephone'];
$fax=$_POST['fax'];
$address=$_POST['address'];
$country=$_POST['country'];
$comment=$_POST['comment'];

# -=-=-=- MIME BOUNDARY
$mime_boundary = "----MSA Shipping----".md5(time());
# -=-=-=- MAIL HEADERS
$to = "dlwijerathna@gmail.com";
//$to = "duminda@dumidesign.com";
//$to = "info@msashipping.com";
$subject = "Information Request from MSA Shipping - Contact Form";
$headers = "From: MSA SHIPPING <webmaster@msashipping.com>\n";
$headers .= "Reply-To: MSA Shipping <webmaster@msashipping.com>\n";
$headers .= "BCC: dumidesign@gmail.com";
$headers .= "MIME-Version: 1.0\n";
$headers .= "Content-Type: multipart/alternative; boundary=\"$mime_boundary\"\n";

$message .= "--$mime_boundary\n";
$message .= "Content-Type: text/html; charset=UTF-8\n";
$message .= "Content-Transfer-Encoding: 8bit\n\n";

$message .= "<html>\n";
$message .= "<body style=\"font-family:Verdana, Verdana, Geneva, sans-serif; font-size:12px; color:#666666;\">\n";

$message .= "<table width=\"800\" height=\"159\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" >";
$message .="<tr>";
$message .="<td height=\"66\" colspan=\"4\" bgcolor=\"#CCCCCC\"></td>";
$message .="</tr>";
$message .="<tr>";
$message .="<td width=\"1%\"></td>";
$message .="<td colspan=\"3\">&nbsp;</td>";
$message .="</tr>";
$message .="<tr>";
$message .="<td>&nbsp;</td>";
$message .="<td width=\"100\"><b>Title</b></td>";
$message .="<td align=\"left\" >:</td>";
$message .="<td>$title</td>";
$message .="<tr>";
$message .="<td>&nbsp;</td>";
$message .="<td><b>Name</b></td>";
$message .="<td>:</td>";
$message .="<td>$name</td>";
$message .="</tr>";
$message .="</tr>";
$message .="<tr>";
$message .="<td>&nbsp;</td>";
$message .="<td><b>E-mail</b></td>";
$message .="<td>:</td>";
$message .="<td>$email</td>";
$message .="</tr>";
$message .="<tr>";
$message .="<td>&nbsp;</td>";
$message .="<td><b>Telephone</b></td>";
$message .="<td>:</td>";
$message .="<td>$telephone</td>";
$message .="</tr>";
$message .="<tr>";
$message .="<td>&nbsp;</td>";
$message .="<td><b>Fax</b></td>";
$message .="<td>:</td>";
$message .="<td>$fax</td>";
$message .="</tr>";
$message .="<tr>";
$message .="<td>&nbsp;</td>";
$message .="<td><b>Country</b></td>";
$message .="<td>:</td>";
$message .="<td>$country</td>";
$message .="</tr>";
$message .="<tr>";
$message .="<td>&nbsp;</td>";
$message .="<td><b>Comments</b></td>";
$message .="<td>:</td>";
$message .="<td>$comment</td>";
$message .="</tr>";
$message .="<tr>";
$message .="<td height=\"21\" colspan=\"4\" bgcolor=\"#CCCCCC\"></td>";
$message .="</tr>";
$message .="</table>";
$message .= "</body>\n";
$message .= "</html>\n";
# -=-=-=- FINAL BOUNDARY
$message .= "--$mime_boundary--\n\n";
# -=-=-=- SEND MAIL
$mail_sent = @mail( $to, $subject, $message, $headers );
//echo $mail_sent ? "Mail sent" : "Mail failed";
if($mail_sent)
{
header('Location:contactus.php?msg=yes');
}
else
{
header('Location:contactus.php?msg=no');
}
?>
webmaster at plumage dot nl
02-Sep-2008 12:53
The work-around for a large quantity of recipients is putting the adresses in the header-section as Bcc adresses.
In this way the mail()-function opens and closes the SMTP connection only once:

<?
$count_recip
= count($recip);//where $recip represents an array of mail-adresses, from MySql-query or otherwise
$count='0';
$headers.="Bcc: ";
while(
$count < $count_recip){
$headers.=$recip[$count].", ";
$count ++;
}
$headers.="admin@mailinglist.com\r\n";
?>
Abner Diaz
26-Aug-2008 07:55
The mail function doesn't work properly under Windows, in case you are going crazy and wondering what is happening.

http://bugs.php.net/bug.php?id=28038

This is not a bug report.  Just letting people know that they are not crazy.
goblitas at khipu dot net
07-Aug-2008 06:14
I have a problem with mail() function on IIS 6, WINDOWS 2003, and PHP, my code work on a linux server, but don't work on my WINDOWS SERVER, mi php.ini is configured with SMTP:mail.khipu.net and from:webmaster@khipu.net, some body know how to solve this problem or maybe is a problem of some rule in my ISA SERVER.

thank you for your comments
bob
15-Jul-2008 11:51
If the Cc or Bcc lines appear in the message body, make sure you're separating header lines with a new line (\n) rather than a carriage return-new line (\r\n). That should come at the very end of the headers.
akam
28-May-2008 04:55
There differenece in body, headers of email (with attachment, without attachment), see this complete example below:
work great for me (LINUX , WIN) and (Yahoo Mail, Hotmail, Gmail, ...)
<?php
$to     
= $_POST['to'];
$email   = $_POST['email'];
$name    = $_POST['name'];
$subject = $_POST['subject'];
$comment = $_POST['message'];

$To          = strip_tags($to);
$TextMessage =strip_tags(nl2br($comment),"<br>");
$HTMLMessage =nl2br($comment);
$FromName    =strip_tags($name);
$FromEmail   =strip_tags($email);
$Subject     =strip_tags($subject);

$boundary1   =rand(0,9)."-"
.rand(10000000000,9999999999)."-"
.rand(10000000000,9999999999)."=:"
.rand(10000,99999);
$boundary2   =rand(0,9)."-".rand(10000000000,9999999999)."-"
.rand(10000000000,9999999999)."=:"
.rand(10000,99999);

 
for(
$i=0; $i < count($_FILES['youfile']['name']); $i++){
if(
is_uploaded_file($_FILES['fileatt']['tmp_name'][$i]) &&
   !empty(
$_FILES['fileatt']['size'][$i]) &&
   !empty(
$_FILES['fileatt']['name'][$i])){
    
$attach      ='yes';
$end         ='';

  
$handle      =fopen($_FILES['fileatt']['tmp_name'][$i], 'rb');
  
$f_contents  =fread($handle, $_FILES['fileatt']['size'][$i]);
  
$attachment[]=chunk_split(base64_encode($f_contents));
  
fclose($handle);

$ftype[]       =$_FILES['fileatt']['type'][$i];
$fname[]       =$_FILES['fileatt']['name'][$i];
}
}

/***************************************************************
 Creating Email: Headers, BODY
 1- HTML Email WIthout Attachment!! <<-------- H T M L ---------
 ***************************************************************/
#---->Headers Part
$Headers     =<<<AKAM
From: $FromName <$FromEmail>
Reply-To: $FromEmail
MIME-Version: 1.0
Content-Type: multipart/alternative;
    boundary="$boundary1"
AKAM;
#---->BODY Part
$Body        =<<<AKAM
MIME-Version: 1.0
Content-Type: multipart/alternative;
    boundary="$boundary1"

This is a multi-part message in MIME format.

--$boundary1
Content-Type: text/plain;
    charset="windows-1256"
Content-Transfer-Encoding: quoted-printable

$TextMessage
--$boundary1
Content-Type: text/html;
    charset="windows-1256"
Content-Transfer-Encoding: quoted-printable

$HTMLMessage

--$boundary1--
AKAM;
/***************************************************************
 2- HTML Email WIth Multiple Attachment <<----- Attachment ------
 ***************************************************************/
 
if($attach=='yes') {

$attachments='';
$Headers     =<<<AKAM
From: $FromName <$FromEmail>
Reply-To: $FromEmail
MIME-Version: 1.0
Content-Type: multipart/mixed;
    boundary="$boundary1"
AKAM;
for(
$j=0;$j<count($ftype); $j++){
$attachments.=<<<ATTA
--$boundary1
Content-Type: $ftype
[$j];
    name="$fname
[$i]"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
    filename="$fname
[$j]"

$attachment
[$j]

ATTA;}

$Body        =<<<AKAM
This is a multi-part message in MIME format.

--$boundary1
Content-Type: multipart/alternative;
    boundary="$boundary2"

--$boundary2
Content-Type: text/plain;
    charset="windows-1256"
Content-Transfer-Encoding: quoted-printable

$TextMessage
--$boundary2
Content-Type: text/html;
    charset="windows-1256"
Content-Transfer-Encoding: quoted-printable

$HTMLMessage

--$boundary2--

$attachments
--$boundary1--
AKAM;}

/***************************************************************
 Sending Email
 ***************************************************************/
$ok=mail($To, $Subject, $Body, $Headers);
echo
$ok?"<h1> Mail Sent</h1>":"<h1> Mail not SEND</h1>";
?>
fogidas at yahoo dot com
15-May-2008 02:18
I think gmail works fine without adding '\n\n' , what doesn't seem to work is the Reply To header. Has anyone paid attention if you try to reply the mail  it takes "From " email and not Reply to.
jyotsnachannagiri at gmail dot com
06-May-2008 11:09
If you are sending an email to Gmail account you need to add two "\n\n" at the end of headers (Don't use single "\n"). If you use single "\n" all the headers will be displayed in the message when received person is viewing the message.

Example:

$headers  = "MIME-Version: 1.0 "."\n";
$headers .= "Content-type: text/html; charset=iso-8859-1 "."\n";
..........
.......
$headers .= "......"."\n\n";
ben at ben-griffiths dot com
27-Mar-2008 11:45
As [apdhanushka at yahoo dot com] stated, you could use PHPMailer to get around being placed in the Spam folder, however I would also reccomend Swiftmailer:

http://www.swiftmailer.org/
apdhanushka at yahoo dot com
30-Jan-2008 02:21
Are you getting spammed while sendig emails using php mail() function to yahoo or hotmail?

 It is a common problem for all using php mail function. To solve this there
are so many answers I have seen in the internet and they do not hit problem
correctly.

Actually the problem here is if we send mails using php mail function we do
not have a signature and other mailing systems thinks that we are spamers.

So the solution is using a free remote smtp host like gmail to send our mails.
It is not hard because we have a free php smtp project called PHPMailer. You
can download it from http://sourceforge.net/project/showfiles.php?group_id=26031.
You do not need to install it on your server and you can upload it to the server with your code.

It is very easy to understand how it is used to send mails using examples
zipped with PHPMailer. The following code is to send emails using gmail and
to do that you have to have a gmail mail account. Which can easily be created
by visiting http://gmail.com. Your mails will
send using that mail account and they will never become spams...

You can follow the following link to get the code to send emails using gmail's free smtp service.
http://bestdeveloper.blogspot.com/
apdhanushka at yahoo dot com
30-Jan-2008 10:05
It is a common problem for all using php mail function. To solve this there
are so many answers I have seen in the internet and they do not hit problem
correctly.

Actually the problem here is if we send mails using php mail function we do
not have a signature and other mailing systems thinks that we are spamers.

So the solution is using a free remote smtp host like gmail to send our mails.
It is not hard because we have a free php smtp project called PHPMailer. You  can download it from http://sourceforge.net/project/showfiles.php?group_id=26031 .
You do not need to install it on your server.

It is very easy to understand how it is used to send mails using examples
zipped with PHPMailer. The following code is to send emails using gmail and
to do that you have to have a gmail mail account. Which can easily be created
by visiting http://gmail.com. Your mails will
send using that mail account and they will never become spams...

To see the complete code for sending emails use following link

http://bestdeveloper.blogspot.com
jano ATSOMERANDOMTEXTjanogarcia es
28-Jan-2008 12:31
This is a simple and quick (dirty?) fix for encoding long UTF-8 email subjects.

<?php

    $subject
= mb_encode_mimeheader($subject,"UTF-8", "B", "\n");

?>

Changing the $transfer_encoding parameter* from B (Base64) to Q (Quoted-Printable) seems to work too.

*See the mb_encode_mimeheader documentation here http://php.net/manual/en/function.mb-encode-mimeheader.php

This one is based on the previously posted solution by J.Halmu http://php.net/manual/en/function.mail.php#75886 , added the two last parameters to prevent long subjects from breaking the email. It worked flawlessly on a RHEL environmet. No further tests, sorry.
Tomix
17-Jan-2008 05:53
send e-mail in utf-8

there is already a solution from omgs. but with a longer subject line there could be problem (splitting the subject line in a encoded character).

here my solution:
----
// hmm no better solution?
function imap8bit(&$item, $key) {
 $item = imap_8bit($item);
}

function email($e_mail, $subject, $message, $headers)
 {
  // add headers for utf-8 message
  $headers .= "\r\n";
  $headers .= "MIME-Version: 1.0\r\n";
  $headers .= "Content-type: text/plain; charset=utf-8\r\n";
  $headers .= "Content-Transfer-Encoding: quoted-printable\r\n";

  // encode subject
  //=?UTF-8?Q?encoded_text?=

  // work a round: for subject with wordwrap
  // not fixed, no possibility to have one in a single char
  $subject = wordwrap($subject, 25, "\n", FALSE);
  $subject = explode("\n", $subject);
  array_walk($subject, imap8bit);
  $subject = implode("\r\n ", $subject);
  $subject = "=?UTF-8?Q?".$subject."?=";

  // encode e-mail message
  $message = imap_8bit($message);

  return(mail("$e_mail", "$subject", "$message", "$headers"));
 }
I.Ruau
02-Dec-2007 04:23
I recently searched for a decent regex to *correctly* validate e-mail addresses according to RFC-2822.

Most regexes I found on the web (including in the comments here) are way too strict.
Then I stumbled upon this compliant parser:
http://code.iamcal.com/php/rfc822/?C=D;O=A

FWIW here is the complete, unrolled regex... which is quite edifying! ;-)
http://code.iamcal.com/php/rfc822/full_regexp.txt

Hope this helps.
hn at nesland dot net
03-Nov-2007 02:37
Tired of idiots and imbeciles who creates unsecure php-code and lets spammers abuse mail()? Try this dirty trick:

With auto_prepend, prepend this file:
<?php
// You need to install pecl-module, runkit.
dl("runkit.so");

// We could rename the function, but that currently makes my apache segfault, but this works :-P
runkit_function_copy ( "mail","intmail" );
runkit_function_remove( "mail" );

function
mail( $to, $subject, $message, $additional_headers = null, $additional_parameters = null ) {

   
$___domain = $_SERVER['SERVER_NAME'];
 
   
$fp = fopen("/tmp/my_super_mail_logg", "a");
   
fwrite( $fp, date("d.m.y H:i:s") . " " . $___domain . ": $to / $subject\n");
   
fclose( $fp );

    return
intmail( $to, $subject, $message, $additional_headers, $additional_parameters );
}
?>

You probably shouldn't log to /tmp, or any other place as the webserver-user, see syslog-functions ;)

And of course you can manipulate the different parameters, like adding custom headers to each email (For instance; "X-From-Web: {$_SERVER['SERVER_NAME']}")..
Ben
04-Oct-2007 09:14
There was a comment that

mail("User Name <username@email.com>","Subject Here",$msg,"From: us@mysite.com");

does not work. I've always used that and never had any issues - from Linux servers. I don't see how this could be different in IE vs Firefox; I've always gotten the same result in both. Just tried it on a Windows server and got this as a bounce back:

<User Name <username@email.com>:
x.x.x.x does not like recipient.
Remote host said: 550 Requested action not taken: 550 No such recipient
Giving up on x.x.x.x.

(Details changed to protect the innocent/guilty (for using a Windows server))

Took me a while to find the bounce until I used ini_set('sendmail_from', 'my@account');

So it is probably  trying to deliver to "User Name <username" instead of simply "username".
largo at email dot pcleak dot com
04-Oct-2007 12:01
hello ok i have this email form right and it is
<?php
if (isset($_REQUEST['email']))
//if "email" is filled out, send email
 
{
 
//send email
 
$email = $_REQUEST['email'] ;
 
$subject = $_REQUEST['subject'] ;
 
$message = $_REQUEST['message'] ;
 
mail( "someone@example.com", "Subject: $subject",
 
$message, "From: $email" );
  echo
"Thank you for using our mail form";
  }
else
//if "email" is not filled out, display the form
 
{
  echo
"<form method='post' action='mailform.php'>
  Email: <input name='email' type='text' /><br />
  Subject: <input name='subject' type='text' /><br />
  Message:<br />
  <textarea name='message' rows='15' cols='40'>
  </textarea><br />
  <input type='submit' />
  </form>"
;
  }
?>
i like it but i want to change like but i want it to ask for sending it "TOO" and it automatically post the sender
phpcoder at cyberpimp dot ig3 dot net
27-Sep-2007 06:51
In addition to the $to parameter restrictions on Windows (ie. address can not be in "name <user@example.com>" format), the same restrictions apply to the parsed Cc and Bcc headers of the $additional_headers parameter.

However, you can include a To header in $additional_parameters which lists the addresses in any RFC-2822 format.  (For display purposes only.  You still need to list the bare addresses in the $to parameter.)
omgs
30-Aug-2007 11:57
I haven't seen in this page a reference about how to properly handle subject encoding when using non-ascii characters. I've found that info at http://www.johanvanmol.org/content/view/34/37/1/3/, which I paste:

"According to RFC 2822, mail header fields, including the subject, MUST be composed of printable US-ASCII characters (i.e., characters that have values between 33 and 126, inclusive). So if you want a subject with accents, you must encode it from your original character set to a US-ASCII character set. There are 2 of ways to do this: quoted-printable or base64.

[...]

Now we have an encoded subject, but our mail reader won't know that. So we need to tell it by formatting our subject as follows: "=?" charset "?" encoding "?" encoded-text "?=" , where charset is the original character set and encoding is either "Q" for Quoted-Printable or "B" for Base64.
E.g The subject containing the Quoted-Printable ISO-8859-1 string "Voilà une message", is written as:
Subject: =?ISO-8859-1?Q?Voil=E0_une_message?=
The Base64 version of the ISO-8859-1 string is:
Subject: =?ISO-8859-1?B?Vm9pbOAgdW5lIG1lc3NhZ2U=?=
The Quoted-Printable version of the UTF-8 string is:
Subject: =?UTF-8?Q?Voil=C3=A0_une_message?=
The Base64 version of the UTF-8 string is:
Subject: =?UTF-8?B?Vm9pbMOgIHVuZSBtZXNzYWdl?=
"

"Raw" non-encoded subjects can work and modern mail clients handle it properly, but I found that at least using utf-8 as encoding, the spam analizers complain stating "BAD HEADER Non-encoded 8-bit data". To prevent this, and taking the info above, I decided to use base64, which at least seems to have specific functions (and because it works, of course). So, one could use the following code:

<?php
...
$charset='UTF-8';
$subject='Subject with extra chars: áéíóú';
$encoded_subject="=?$charset?B?".base64_encode($subject)."?=\n";
$to=mail@foo.com;
$body='This is the body';
$headers="From: ".$from."\n"
   
. "Content-Type: text/plain; charset=$charset; format=flowed\n"
   
. "MIME-Version: 1.0\n"
   
. "Content-Transfer-Encoding: 8bit\n"
   
. "X-Mailer: PHP\n";
mail($to,$encoded_subject, $body,$headers);

?>

Of course, this can be "enhanced" by encoding only if there are non-ASCII characters, but I don't think I need it. Maybe the CPU work, used time and results don't deserve it.
Gianluigi_Zanettini-MegaLab.it
10-Aug-2007 09:57
Please note that using an address in this format "Zane, CEO - MegaLab.it" <myaddrr@mydomain> (" are needed due to comma) works as expected under *nix, but WON'T WORK under Windows.

This is an example

<?php
mail
("\"Zane, CEO - MegaLab.it\" <myaddrr@mydomain>", "prova da test_zane", "dai funziona...");
?>

It works under *unix, but it doensn't under Win: different error are reported:

Warning: mail() [function.mail]: SMTP server response: 553 5.0.0 <"Zane>... Unbalanced '"'

Warning: mail() [function.mail]: SMTP server response: 501 5.5.4 Invalid Address
pavolzetor at gmail dot com
01-Aug-2007 06:47
if you send mail to gmail.com you don't use "\r\n" and you use only "\n" in headers
bsaul at inwind dot it
24-Jun-2007 12:19
First excuse me for bad english. I'm working on a function that send html or text or both, e-mail message. I try all the example but no one working on my system (windows XP with PostCast SMTP server). Finally i try this and work. I hope your find useful:

function mailTo ($from, $to, $oggetto, $contenuto, $type = "both", $reply = true) {

    // If $contenuto == file reading
    $messaggio = @file_get_contents( $content, 1);
    if ($messaggio) { $contenuto = $messaggio; }
    $messaggio = '';

    // Standar Header
    $crlf = chr(10) . chr(13);
    $intestazione  = "To: {$to}" . $crlf;
    $intestazione .= "From: {$from}" . $crlf;
    $intestazione .= "Return-Path: " . (($reply)? $from : substr_replace($from, "noreply", 0, strpos($from, '@'))) . $crlf;
    $intestazione .= 'Reply-To: ' .(($reply)? $from : substr_replace($from, "noreply", 0, strpos($from, '@'))) . $crlf;
   $intestazione .= 'X-Mailer: PHP/' . phpversion() . $crlf;

    // MIME boundary
    $separatore = 'PHP' . md5(uniqid(time()));
    // MIME Header
    $intestazione .= 'MIME-Version: 1.0' . $crlf;

    switch ($type){
        case 'html' :
                        // Header for client non MIME compatible
            $intestazione .= 'Content-Type: text/html; charset=ISO-8859-15' . $crlf;
            $intestazione .= 'Content-Transfer-Encoding: 7bit' . $crlf;
            $messaggio .= "\n{$contenuto}\n";
            break;

        case 'both' :
            $intestazione .= "Content-Type: multipart/alternative;\n\tboundary=\"" . $separatore . '"' . $crlf;
            // Create message for no mime client
            $messaggio .= "For English People: This is a multi-part message in MIME format.\nIf you are reading this, consider upgrading your e-mail client to a MIME-compatible client.\n";
            $messaggio .= "For Italian People: Questo è un messaggio MIME.\nSe si stà leggendo questa nota, consigliamo l\'aggiornamento del programma di posta elettronica con uno compatibile MIME";
            $messaggio .= "\n--{$separatore}\n";
            $messaggio .= "Content-Type: text/plain; charset=ISO-8859-15\n";
            $messaggio .= "Content-Transfer-Encoding: 7bit\n\n";

        case 'text' :
            $messaggio .= strip_tags($contenuto);
            if ($type == 'both') {
                $messaggio .= "\n--{$separatore}\n";;
                $messaggio .= "Content-Type: text/html; charset=ISO-8859-15\n";
                $messaggio .= "Content-Transfer-Encoding: 7bit\n";
                $messaggio .= "\n{$contenuto}";
                $messaggio .= "\n--{$separatore}\n";
            }
    }

    // Send MAIL
    return  mail($to, $oggetto, $messaggio, $intestazione);

}
J.Halmu
20-Jun-2007 02:10
I use text/plain charaset=iso-8859-1 and get bad headers complain from amavis. This helped me:

[code]
$subject = mb_encode_mimeheader('ääööö test test öäöäöä','UTF-8');
[/code]

php-version 5.2.2
Alex Jaspersen
31-May-2007 09:03
For qmail users, I have written a function that talks directly to qmail-queue, rather than going through the sendmail wrapper used by mail(). Thus it allows more direct control over the message (for example, you can adapt the function to display "undisclosed recipients" in to the To: header). It also performs careful validation of the e-mail addresses passed to it, making it more difficult for spammers to exploit your scripts.

Please note that this function differs from the mail() function in that the from address must be passed as a _separate_ argument. It is automatically put into the message headers and _does not_ need to be included in $additional_headers.

$to can either be an array or a single address contained in a string.
$message should not contain any carriage return characters - only linefeeds.

No validation is performed on $additional_headers. This is mostly unnecessary because qmail will ignore any additional To: headers injected by a malicious user. However if you have some strange mail setup it might be a problem.

The function returns false if the message fails validation or is rejected by qmail-queue, and returns true on success.

<?php
function qmail_queue($to, $from, $subject, $message, $additional_headers = "")
{
   
// qmail-queue location and hostname used for Message-Id
   
$cmd = "/var/qmail/bin/qmail-queue";
   
$hostname = trim(file_get_contents("/var/qmail/control/me"));
   
   
// convert $to into an array
   
if(is_scalar($to))
       
$to = array($to);
   
   
// BEGIN VALIDATION
    // e-mail address validation
   
$e = "/^[-+\\.0-9=a-z_]+@([-0-9a-z]+\\.)+([0-9a-z]){2,4}$/i";
   
// from address
   
if(!preg_match($e, $from)) return false;
   
// to address(es)
   
foreach($to as $rcpt)
    {
        if(!
preg_match($e, $rcpt)) return false;
    }
   
   
// subject validation (only printable 7-bit ascii characters allowed)
    // needs to be adapted to allow for foreign languages with 8-bit characters
   
if(!preg_match("/^[\\040-\\176]+$/", $subject)) return false;
   
   
// END VALIDATION
   
    // open qmail-queue process
   
$dspec = array
    (
        array(
"pipe", "r"), // message descriptor
       
array("pipe", "r") // envelope descriptor
   
);
   
$pipes = array();
   
$proc = proc_open($cmd, $dspec, $pipes);
    if(!
is_resource($proc)) return false;
   
   
// write additional headers
   
if(!empty($additional_headers))
    {
       
fwrite($pipes[0], $additional_headers . "\n");
    }
   
   
// write to/from/subject/date/message-ID headers
   
fwrite($pipes[0], "To: " . $to[0]); // first recipient
   
for($i = 1; $i < sizeof($to); $i++) // additional recipients
   
{
       
fwrite($pipes[0], ", " . $to[$i]);
    }
   
fwrite($pipes[0], "\nSubject: " . $subject . "\n");
   
fwrite($pipes[0], "From: " . $from . "\n");
   
fwrite($pipes[0], "Message-Id: <" . md5(uniqid(microtime())) . "@" . $hostname . ">\n");
   
fwrite($pipes[0], "Date: " . date("r") . "\n\n");
   
fwrite($pipes[0], $message);
   
fwrite($pipes[0], "\n");
   
fclose($pipes[0]);
   
   
// write from address and recipients
   
fwrite($pipes[1], "F" . $from . "\0");
    foreach(
$to as $rcpt)
    {
       
fwrite($pipes[1], "T" . $rcpt . "\0");
    }
   
fwrite($pipes[1], "\0");
   
fclose($pipes[1]);
   
   
// return true on success.
   
return proc_close($proc) == 0;
}
?>
James Butler
24-May-2007 10:15
Re: "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."

SERVER:
 PHP 5.0.4
 Fedora Core 4
 Apache 2.0
 Sendmail 8.13.7
 SMTP: localhost

CLIENT:
 Windows 98SE
 Mozilla Firefox 2.0.0.3
 Microsoft Internet Explorer 6.0.2800.1106

COMMAND:
 mail("User Name <username@email.com>","Subject Here",$msg,"From: us@mysite.com");

Using Firefox, no problems with the above command.
Using MSIE, won't send mail "to" address formatted as above.

COMMAND 2:
 mail("username@email.com","Subject Here",$msg,"From: us@mysite.com");

Works fine from both clients.

I mention this because it appears there is some interaction between the client and MTA that is unaccounted for in the above quote from this doc page.
junk at hostelz dot com
21-Mar-2007 10:56
Unless I'm confused, I suspect that in the code from "rsjaffe at gmail dot com" above, "\\r" and "\\n" should actually be "\r" and "\n".
Josh
09-Mar-2007 08:05
While trying to send attachments I ran into the problem of having the beginning part of my encoded data being cut off.

A fact that I didn't see mentioned anywhere explicitly (except maybe in the RFC, which admittedly I didn't read fully) was that two newlines are required before you start the encoded data:

Content-Transfer-Encoding: base64\n
Content-Type: application/zip; name="test_file.zip"\n
\n  //<--- if this newline isn't here your data will get cut off
DATA GOES HERE
hans111 at yahoo dot com
01-Mar-2007 06:54
I had a lot of trouble trying to send multipart messages to gmail accounts until I discovered gmail does not like carriage returns, even under unix I have to use only new lines (\n) and forget about the (\r) . Other email clients such as eudora, outlook, hotmail or yahoo seem not to have issues about the "missing" \r . Hope it helps.
bigtree at dontspam dot 29a dot nl
28-Feb-2007 02:46
Since lines in $additional_headers must be separated by \n on Unix and \r\n on Windows, it might be useful to use the PHP_EOL constant which contains the correct value on either platform.

Note that this variable was introduced in PHP 5.0.2 so to write portable code that also works in PHP versions before that, use the following code to make sure it exists:

<?php
if (!defined('PHP_EOL')) define ('PHP_EOL', strtoupper(substr(PHP_OS,0,3) == 'WIN') ? "\r\n" : "\n");
?>
andy at andybev dot com
19-Feb-2007 02:56
I'm copying Ben Cooke's note from the main mail page into here because I didn't find it initially. The issue described below caused me a lot of problems because of Postfix converting a single \r\n into double new lines, resulting in corrupted mail.

=====================================================

Note that there is a big difference between the behavior of this function on Windows systems vs. UNIX systems. On Windows it delivers directly to an SMTP server, while on a UNIX system it uses a local command to hand off to the system's own MTA.

The upshot of all this is that on a Windows system your  message and headers must use the standard line endings \r\n as prescribed by the email specs. On a UNIX system the MTA's "sendmail" interface assumes that recieved data will use UNIX line endings and will turn any \n to \r\n, so you must supply only \n to mail() on a UNIX system to avoid the MTA hypercorrecting to \r\r\n.

If you use plain old \n on a Windows system, some MTAs will get a little upset. qmail in particular will refuse outright to accept any message that has a lonely \n without an accompanying \r.
admin at chatfamy dot com
30-Jan-2007 10:37
One thing it can be difficult to control with this function is the envelope "from" address. The envelope "from" address is distinct from the address that appears in the "From:" header of the email. It is what sendmail uses in its "MAIL FROM/RCPT TO" exchange with the receiving mail server. It also typically shows up in the "Return-Path:" header, but this need not be the case. The whole reason it is called an "envelope" address is that appears _outside_ of the message header and body, in the raw SMTP exchange between mail servers.

The default envelope "from" address on unix depends on what sendmail implementation you are using. But typically it will be set to the username of the running process followed by "@" and the hostname of the machine. In a typical configuration this will look something like apache@box17.isp.net.

If your emails are being rejected by receiving mail servers, or if you need to change what address bounce emails are sent to, you can change the envelope "from" address to solve your problems.

To change the envelope "from" address on unix, you specify an "-r" option to your sendmail binary. You can do this globally in php.ini by adding the "-r" option to the "sendmail_path" command line. You can also do it programmatically from within PHP by passing "-r address@domain.com" as the "additional_parameters" argument to the mail() function (the 5th argument). If you specify an address both places, the sendmail binary will be called with two "-r" options, which may have undefined behavior depending on your sendmail implementation. With the Postfix MTA, later "-r" options silently override earlier options, making it possible to set a global default and still get sensible behavior when you try to override it locally.

On Windows, the the situation is a lot simpler. The envelope "from" address there is just the value of "sendmail_from" in the php.ini file. You can override it locally with ini_set().
tdaniel at univ dot haifa dot ac dot il
26-Oct-2006 02:17
I had trouble getting multiple emails sent for Outlook accounts (a single PHP page performed 2 mail() calls).

The PHP mail() function works correctly, but the same mails that were recieved on a private POP3 server were randomly missing by our intranet Outlook exchange server.

If you have the same problem, try to verify that the "Message-ID: " is unique at the $headers string. i.e.

<?php
$headers
= [...] .
"Message-ID: <". time() .rand(1,1000). "@".$_SERVER['SERVER_NAME'].">". "\r\n" [...];
?>

(rand() is used only for demonstration purposes. a better way is to use an index variable that increments (i++) after each mail)

I noticed that when multiple messeges were sent simultaneously, the message-id was the same (probably there was no miliseconds differential). My guess is that Outlook is collating messages with the same message-ID; a thing that causes only one email to pass to the Outlook inbox instead of a few.
i5513
27-Sep-2006 11:30
[EDITOR's NOTE: Following based off of a note originally by marcelo dot maraboli at usm dot cl which has been removed.]

I had a trouble with marcelo' function, I had to add "$val == 63" condition into "if" sentence for '?' character

# From marcelo post:
function encode_iso88591($string)
{
  $text = '=?iso-8859-1?q?';
 
  for( $i = 0 ; $i < strlen($string) ; $i++ )
  {
   $val = ord($string[$i]);
   if($val > 127 or $val == 63)
   {
     $val = dechex($val);
     $text .= '='.$val;
   }
   else
   {
       $text .= $string[$i];
   }
 
  }
  $text .= '?=';
 
  return $text;
}

and later use:

       // create email
       $msg = wordwrap($msg, 70);
       $to = "destination@company.com";
       $subject = encode_iso88591("hoydía caminé !!");
       $headers =    "MIME-Versin: 1.0\r\n" .
               "Content-type: text/plain; charset=ISO-8859-1; format=flowed\r\n" .
               "Content-Transfer-Encoding: 8bit\r\n" .
               "From: $from\r\n" .
               "X-Mailer: PHP" . phpversion();

       mail($to, $subject, $msg, $headers);
johniskew2
19-Sep-2006 07:28
An important rule of thumb, because it seems few really follow it and it can alleviate so many headaches: When filtering your email headers for injection characters use a regular expression to judge whether the user's input is valid.  For example to see if the user entered a valid e-mail address use something like  [a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}.  Dont try to filter out bad characters (like searching for LF or CR), because you will ALWAYS miss something.  You can be sure your application is more secure going this route....provided the regular expression is valid!  This same point goes for any sort of form input not just for sending out emails.
thomas at p-devion dot de
24-Aug-2006 08:46
Change the function addattachment for multipartmail to auto detect the mime_content_type ...

     function addattachment($file){
         $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: ".mime_content_type($file)."; 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;
     }
panoramical at gmail dot com
28-Jul-2006 02:19
Searched for ages on the internet trying to find something that parses EML files and then sends them...for all of you who want to send an EML files you first have to upload it, read it, then delete it. Here's my function...it's specialised for a single form where the user uploads the EML file.

<?php

if(isset($_POST['submit']))
{

// Reads in a file (eml) a user has inputted
function eml_read_in()
{

   
$file_ext = stristr($_FILES['upload']['name'], '.');
   
   
// If it is an eml file
   
if($file_ext == '.eml')
    {
   
       
// Define vars
       
$dir = 'eml/';
       
$file = $dir.basename($_FILES['upload']['name']);
       
$carry = 'yes';
       
       
// Try and upload the file
       
if(move_uploaded_file($_FILES['upload']['tmp_name'], $file))
        {
       
           
// Now attempt to read the file
           
if($eml_file = file($file))
            {
           
               
// Create the array to store preliminary headers
               
$headers = array();
               
$body = '';
               
$ii = -1;

               
               
// For every line, carry out this loop
               
foreach($eml_file as $key => $value)
                {
               
                   
$pattern = '^<html>';
                   
                    if(((
eregi($pattern, $value)))||($carry == 'no'))
                    {
                   
                       
// Stop putting data into the $headers array
                       
$carry = 'no';
                       
$i++;
                       
$body .= $value;
                       
                    }
                   
                    else
                    {   
                       
                       
// Separate each one with a colon
                       
if(($eml_file_expl = explode(':', $value))&&($carry == 'yes'))
                        {

                       
                           
// The row has been split in half at least...
                           
if(isset($eml_file_expl[1]))
                            {
       
                               
// Put it into the preliminary headers
                               
$headers[$eml_file_expl[0]] = $eml_file_expl[1];
                           
                               
// There might be more semicolons in it...
                               
for($i=2;$i<=$count;$i++)
                                {
                           
                                   
// Add the other values to the header
                                   
$headers[$eml_file_expl[0]] .= ':'.$eml_file_expl[$i];
                                   
                                }
                           
                            }   
                           
                        }       
                   
                    }
                   
                }
               
               
// Clear up the headers array
               
$eml_values = array();
               
$eml_values[to] = $headers[To];
               
$eml_values[from] = $headers[From];
               
$eml_values[subject] = $headers[Subject];
               
$eml_values['reply-to'] = $headers['Reply-To'];
               
$eml_values['content-type'] = $headers['Content-Type'];
               
$eml_values[body] = $body;
               
               
unlink($file);
       
                return
$eml_values;
               
               
                       
            }
           
        }
       
        else
        {
       
            return
'<p>File not uploaded - there was an error</p>';
                       
        }
       
    }
   
}   

// Takes information automatically from the $_FILES array...
$eml_pattern = eml_read_in()

// Headers definable...through eml_read_in() again, but I'm guessing they'll be the same for each doc...

if(mail($eml_pattern[to], $eml_pattern[subject], $eml_pattern[content], $headers)) echo 'Mail Sent';

?>
24-Jul-2006 06:55
correction for class multipartmail

<?php
function addmessage($msg = "", $ctype = "text/plain"){
        
$this->parts[0] ....
?>

if you are adding attachment first and then addmessage you can easy overwrite added attachment - better use

<?php

function addmessage($msg = "", $ctype = "text/plain"){
        
$this->parts[count($this->parts)] ....

?>
sander at cartel dot nl
20-Jul-2006 01:26
I found out that a ms server (ESMTP MAIL Service, Version: 5.0.2195.6713) also had the problem using CRLF in the headers:

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.

The suggested fix works.

Sander
rsjaffe at gmail dot com
22-May-2006 12: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...
steve at stevewinnington dot co dot uk
13-Mar-2006 06: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
11-Mar-2006 08: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
07-Mar-2006 07: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.
Mailer
05-Mar-2006 03: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/
leonard_orb at future-data dot de
14-Feb-2006 11: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 11:27
Hi,
I'm using phpmailer from http://phpmailer.sourceforge.net/

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

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

With regards,Hossein
php at nioubi dot com
15-Nov-2005 01: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 04: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 02: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
03-Sep-2005 08: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 03: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
25-Jul-2005 08: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");
gregBOGUS at BOGUSlorriman dot com
21-Jun-2005 01: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 09: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
javier at zincro dot com
31-May-2005 07: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 10: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)
daniel at tamm-tamm dot de
01-May-2005 05: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
26-Apr-2005 08: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 02: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.
18-Apr-2005 10: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.
gregBOGUS at BOGUSlorriman dot com
06-Apr-2005 03: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 05: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 07: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 02: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 02: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
18-Feb-2005 10: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 04: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 04: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 12: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 04: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

?>

Mailparse> <ezmlm_hash
Last updated: Fri, 30 Jan 2009
 
 
show source | credits | sitemap | contact | advertising | mirror sites