A new update for PHP has broken a few mailing scripts that a few of our clients use (https://bugs.php.net/bug.php?id=68776)
More specifically, the script sends an email with an attachment - I wrote these using some guides from other sites however it now appears that i've been ill advised as its not technically the correct way to do it.
Original (now broken code) below:
function mail_attachment($filename, $path, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
$file = $path.$filename;
$file_size = filesize($file);
$handle = fopen($file, "r");
$content = fread($handle, $file_size);
fclose($handle);
$content = chunk_split(base64_encode($content));
$uid = md5(uniqid(time()));
$name = basename($file);
$header = "From: ".$from_name." <".$from_mail.">\r\n";
$header .= "Reply-To: ".$replyto."\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";
$header .= "This is a multi-part message in MIME format.\r\n";
$header .= "--".$uid."\r\n";
$header .= "Content-type:text/plain; charset=iso-8859-1\r\n";
$header .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$header .= $message."\r\n\r\n";
$header .= "--".$uid."\r\n";
$header .= "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n";
$header .= "Content-Transfer-Encoding: base64\r\n";
$header .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n";
$header .= $content."\r\n\r\n";
$header .= "--".$uid."--";
error_reporting(E_ALL);
if (mail($mailto, $subject, "", $header)) {
echo "Mail Sent Successfully to " . $mailto ."<br/>"; // or use booleans here
} else {
echo "Mail NOT Sent to " .$mailto ."<br/>";
}
There are now more checks on the header field, which means data which was being stuffed into the header should now really be in the message. See the changes I made to get this working with our webservers (highlighted in yellow):
function mail_attachment($filename, $path, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
$file = $path.$filename;
$file_size = filesize($file);
$handle = fopen($file, "r");
$content = fread($handle, $file_size);
fclose($handle);
$content = chunk_split(base64_encode($content));
$uid = md5(uniqid(time()));
$name = basename($file);
$header = "From: ".$from_name." <".$from_mail.">\r\n";
$header .= "Reply-To: ".$replyto."\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";
(THIS ENTIRE LINE HAS BEEN REMOVED)
$nmessage = "--".$uid."\r\n";
$nmessage .= "Content-type:text/plain; charset=iso-8859-1\r\n";
$nmessage .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$nmessage .= $message."\r\n\r\n";
$nmessage .= "--".$uid."\r\n";
$nmessage .= "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n";
$nmessage .= "Content-Transfer-Encoding: base64\r\n";
$nmessage .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n";
$nmessage .= $content."\r\n\r\n";
$nmessage .= "--".$uid."--";
error_reporting(E_ALL);
if (mail($mailto, $subject, $nmessage, $header)) {
echo "Mail Sent Successfully to " . $mailto ."<br/>"; // or use booleans here
} else {
echo "Mail NOT Sent to " .$mailto ."<br/>";
}
}
And that sorted it out - I hope this helps someone as I had a hell of a time trying to work out what the error message meant and its been pretty vague. Add to this the comments on the PHP bug fix page which aren't that helpful and its quite difficult to sort out. Please +1/share this if it helps you so it can help others
More specifically, the script sends an email with an attachment - I wrote these using some guides from other sites however it now appears that i've been ill advised as its not technically the correct way to do it.
Original (now broken code) below:
function mail_attachment($filename, $path, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
$file = $path.$filename;
$file_size = filesize($file);
$handle = fopen($file, "r");
$content = fread($handle, $file_size);
fclose($handle);
$content = chunk_split(base64_encode($content));
$uid = md5(uniqid(time()));
$name = basename($file);
$header = "From: ".$from_name." <".$from_mail.">\r\n";
$header .= "Reply-To: ".$replyto."\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";
$header .= "This is a multi-part message in MIME format.\r\n";
$header .= "--".$uid."\r\n";
$header .= "Content-type:text/plain; charset=iso-8859-1\r\n";
$header .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$header .= $message."\r\n\r\n";
$header .= "--".$uid."\r\n";
$header .= "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n";
$header .= "Content-Transfer-Encoding: base64\r\n";
$header .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n";
$header .= $content."\r\n\r\n";
$header .= "--".$uid."--";
error_reporting(E_ALL);
if (mail($mailto, $subject, "", $header)) {
echo "Mail Sent Successfully to " . $mailto ."<br/>"; // or use booleans here
} else {
echo "Mail NOT Sent to " .$mailto ."<br/>";
}
There are now more checks on the header field, which means data which was being stuffed into the header should now really be in the message. See the changes I made to get this working with our webservers (highlighted in yellow):
function mail_attachment($filename, $path, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
$file = $path.$filename;
$file_size = filesize($file);
$handle = fopen($file, "r");
$content = fread($handle, $file_size);
fclose($handle);
$content = chunk_split(base64_encode($content));
$uid = md5(uniqid(time()));
$name = basename($file);
$header = "From: ".$from_name." <".$from_mail.">\r\n";
$header .= "Reply-To: ".$replyto."\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";
(THIS ENTIRE LINE HAS BEEN REMOVED)
$nmessage = "--".$uid."\r\n";
$nmessage .= "Content-type:text/plain; charset=iso-8859-1\r\n";
$nmessage .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$nmessage .= $message."\r\n\r\n";
$nmessage .= "--".$uid."\r\n";
$nmessage .= "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n";
$nmessage .= "Content-Transfer-Encoding: base64\r\n";
$nmessage .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n";
$nmessage .= $content."\r\n\r\n";
$nmessage .= "--".$uid."--";
error_reporting(E_ALL);
if (mail($mailto, $subject, $nmessage, $header)) {
echo "Mail Sent Successfully to " . $mailto ."<br/>"; // or use booleans here
} else {
echo "Mail NOT Sent to " .$mailto ."<br/>";
}
}
And that sorted it out - I hope this helps someone as I had a hell of a time trying to work out what the error message meant and its been pretty vague. Add to this the comments on the PHP bug fix page which aren't that helpful and its quite difficult to sort out. Please +1/share this if it helps you so it can help others
Saved my life dude
ReplyDeleteGood call - thanks - I added a link from SO page to here..
ReplyDeleteThanks ..
ReplyDeleteThanks Buddy
ReplyDeletethanks buddy..:)
ReplyDeletebrilliant A++
ReplyDeleteThank you - fixed a really old backup script I had!
ReplyDeletethis saved my bacon! THANKS for posting!!!
ReplyDeleteBest...
ReplyDeleteAny reason you can think of that gmail webmail can read an attachment but Outlook can't read it? Outlook shows the size as 113b
ReplyDeleteThank you for your time.
I figure out my error. Thanks again the great example!
ReplyDeleteThanks, not exactly saved my life but still solved easily my problem after switching PHP versions on the server.
ReplyDeleteAwesome. Thanks a million - reading your post was like winning Powerball! (considering that our php upgrade caused the emails with attachments to stop working)
ReplyDeleteThank you buddy ! :)
ReplyDeletethanksmate,
ReplyDeleteit helps a lot. Saved my day.
Thanks for share
ReplyDeleteIt works with attached inline images too.
ReplyDeletethanks
It works for me Thank you
ReplyDeleteThanks :)
ReplyDeleteThaanks!
ReplyDeleteWhat about attachments, if want to send any attachments than what will do? Please help me out
ReplyDelete