I can't get the emails to send, the script says the email was sent but my smtp (QK SMTP) shows nothing being sent. should i use a different smtp? any suggestions? it needs to be windows...
Here ya go. I took Mr. Kwitko's code and modified it to work with multiple attachments. Want 1 attachment? Want 2 attachments? Want 3 attachments? Fine! I'm sure it will work with more than 3, but that's as high as I've tested, thus far.
I use Courier for my e-mail so I can't verify it will work for most client, but I doubt any of the popular mail clients will have any difficulty with the emails.
[php]
function sendMail() {
if (!isset ($_POST)) { //Oops, forgot your email addy!
die ("<p>Oops! You forgot to fill out the email address! Click on the back arrow to go back</p>");
} else {
$to_name = stripslashes($_POST);
$from_name = stripslashes($_POST);
$subject = stripslashes($_POST);
$body = stripslashes($_POST);
$to_email = $_POST;
$filecount = 0;
foreach($_FILES as $file => $value) {
$attachment[(int)$filecount] = $_FILES[$file];
$attachment_name[(int)$filecount] = $_FILES[$file];
if (is_uploaded_file($attachment[(int)$filecount])) { //Do we have a file uploaded?
$fp = fopen($attachment[(int)$filecount], "rb"); //Open it
$data[(int)$filecount] = fread($fp, filesize($attachment[(int)$filecount])); //Read it
$data[(int)$filecount] = chunk_split(base64_encode($data[(int)$filecount])); //Chunk it up and encode it as base64 so it can emailed
fclose($fp);
$filecount++;
}
}
//Let's start our headers
$headers = "From: $from_name<" . $_POST . ">\n";
$headers .= "Reply-To: <" . $_POST . ">\n";
$headers .= "MIME-Version: 1.0\n";
$headers .= "Content-Type: multipart/related; type=\"multipart/alternative\"; boundary=\"----=MIME_BOUNDRY_main_message\"\n";
$headers .= "X-Sender: $from_name<" . $_POST . ">\n";
$headers .= "X-Mailer: PHP4\n";
$headers .= "X-Priority: 3\n"; //1 = Urgent, 3 = Normal
$headers .= "Return-Path: <" . $_POST . ">\n";
$headers .= "This is a multi-part message in MIME format.\n";
$headers .= "
=MIME_BOUNDRY_main_message \n";
$headers .= "Content-Type: multipart/alternative; boundary=\"----=MIME_BOUNDRY_message_parts\"\n";
$message = "
=MIME_BOUNDRY_message_parts\n";
$message .= "Content-Type: text/plain; charset=\"iso-8859-1\"\n";
$message .= "Content-Transfer-Encoding: quoted-printable\n";
$message .= "\n";
/* Add our message, in this case it's plain text. You could also add HTML by changing the Content-Type to text/html */
$message .= "$body\n";
$message .= "\n";
$message .= "
=MIME_BOUNDRY_message_parts--\n";
$message .= "\n";
print "Mail sent. Thank you for using the MyNewName5333 Mailer.";
}
}
[/php]
You'll see some superfluous int casts. If that bothers you, take them out.
I put them in when I got some errors in an attempt to make sure integers were being seen.
Ok, I got tired of seeing 3 places for attachments because:
1) Most e-mails have no attachments, so they went unused but didn't go without wasting screen space.
2) Sometimes more than 3 attachments are needed.
So, I went digging around and found a way to dynamically alter tables and create INPUT elements. I've taken out the From name and From email because I've hard-coded that in. If you want to have to input that each time then feel free to add that back to the table . . . it's pretty simple to do.
First, you'll need to edit the BODY tag to call a function onLoad.
Now, all you'll have to do is click on the "Add attachment" button that shows up on the Subject line. Each time the button is clicked another row is added to the table with another file input element. Want 1 attachment? Click the button once. Want 37 attachments? Click it 37 times.
Hi
Just like to thank Kwitko for the script first of all and ask a few things about it.
The script works good for me apart from it sends 3 copies of the attachement for some reason? Any idea why?
Also how would i make it that the script will only accept certain extensions? would this help with people sending a malicious script or virus?
thanks again
Al
0
KwitkoSheriff of Banning (Retired)By the thing near the stuffIcrontian
edited December 2004
I have some code to check for file extensions:
[PHP]$allowedext = new array('jpg', 'gif', 'png');
$ext = substr($_FILES, strrpos($_FILES, '.') + 1);
if (!in_array($ext, $allowedext)) {
unlink($_FILES);
exit("File type $ext is not allowed.");
}
[/PHP]
You would throw this in before the part that encodes the files to base64.
</body>
</html>
[/php]
that was the same up at the top. It has codes at the bottom that are still there, y is that. Plus it does not do anything when you press send.
0
KwitkoSheriff of Banning (Retired)By the thing near the stuffIcrontian
I am new to PHP world and I am trying to send mail attachment through your given code. But at the time of sending this mail to @yahoo.com or @gmail.com it's just sending attachment only. No Message with the mail. What should I do now. Also while I am sending this message to POP3 account it's getting done. Problem is with @yahoo.com and all only. Please send me reply asap. It's very urgent.
As promised. Now I didn't add any error checking or formatting. My goal was simply to make sure the MIME encoding was done right. MIME headers are *very* finicky. If you want to add more attachments, you could foreach or while the chunk routine.
//EDIT: added some additional comments. I realized after posting that it's kind of silly to add the MIME boundary if you're not neccessarily sending an attachment, so the encoding routine plus the boundaries for the attachment should really be conditional. Then again, the whole purpose of this script is so you can send attachments, right?
If you send mail to a regular POP3 it works, but if you send mail to Yahoo! or GMail it only sends the attachment? That's what I think you said, but I am not sure.
As promised. Now I didn't add any error checking or formatting. My goal was simply to make sure the MIME encoding was done right. MIME headers are *very* finicky. If you want to add more attachments, you could foreach or while the chunk routine.
//EDIT: added some additional comments. I realized after posting that it's kind of silly to add the MIME boundary if you're not neccessarily sending an attachment, so the encoding routine plus the boundaries for the attachment should really be conditional. Then again, the whole purpose of this script is so you can send attachments, right?
I have used this script and eveything works great. But if i submit the form without adding an attachment the email that comes through to my outlook has a .dat file attached. is there anyway this can be removed.
I sent you an emai, but it would be beneficial to have this here as well. I failed to get the filetype check working.
Errors from the "new array" and the $ext code line wasn't getting anything from the code as I tried to print that value.
I placed it just above
[PHP]if (is_uploaded_file($attachment))
{ //Do we have a file uploaded?
$fp = fopen($attachment, "rb"); //Open it
$data = fread($fp, filesize($attachment)); //Read it
$data = chunk_split(base64_encode($data)); //Chunk it up and encode it as base64 so it can emailed
fclose($fp);
}
[/PHP]
Also tried it in between, above the "$data = chunk etc.. part" without much luck.
I was hoping you could explain a bit more how to get this working with the PHP form. The form is working fine for me, except I cannot get this check, which is very important for us.
I have some code to check for file extensions:
[PHP]$allowedext = new array('jpg', 'gif', 'png');
$ext = substr($_FILES, strrpos($_FILES, '.') + 1);
if (!in_array($ext, $allowedext)) {
unlink($_FILES);
exit("File type $ext is not allowed.");
}
[/PHP]
You would throw this in before the part that encodes the files to base64.
Kwitko your code works great, but there is one annoying thing. When no attachments are sent MS Outlook displays some ATT000xx.dat attachment. Can this be solved? Please consider that i am totaly new to PHP, i have only ASP experience.
Try replacing the sendMail() function with this code and see if it does what you're wanting. If you had made any modifications to the sendMail() function you will have to add those back in.
[php]
function sendMail()
{
if (!isset ($_POST)) { //Oops, forgot your email addy!
die ("<p>Oops! You forgot to fill out the email address! Click on the back arrow to go back</p>");
} else {
$to_name = stripslashes($_POST);
$from_name = stripslashes($_POST);
$subject = stripslashes($_POST);
$body = stripslashes($_POST);
$to_email = $_POST;
if ($ok == 1) {
print "Mail sent to $to_name ($to_email).";
} else {
print "Mail did not send. Please press the <b>back</b> button and re-submit the e-mail.";
}
}
}
[/php]
Try replacing the sendMail() function with this code and see if it does what you're wanting. If you had made any modifications to the sendMail() function you will have to add those back in.
Thanks a million! It works perfectly! Sorry for delayed response, i was not able to answer sooner.
Whats up guys, used this code in a couple forms I made for a client.
It worked perfectly (and still works on my email account) until they changed their server to an in-house custom built server.
So I got a call syaing they were'nt recieveing the emails at all. I changed the code to my email address and it works fine, so how could they not be recieving emails?
On previous posts that dealt with this the response was to change their php.ini file...how would I access that and what would I change?
Thanks!
0
KwitkoSheriff of Banning (Retired)By the thing near the stuffIcrontian
edited April 2007
Check php.ini and see if the the Sendmail line is configured correctly. It should be /path/to/sendmail -t. The directive in php.ini looks like this:
Thanks Kwitko, I was hoping to get a repsonse from the author himself...
I sent my network guy an email and he's gonna look into that.
Here's another interesting piece of the puzzle. Another web developer here (who recently left) wrote a form that submits a resume as a .txt so it can be entered into an Access DB via a parsing program. (The client had already paid for the access databse, so we couldn't get them to switch to MySQL)
So the client fills in the resume & submits the form, which creates a .txt file and sends it to their HR department as an attachment in an email...Now supposedly they are getting these emails!? Does this mean that the above theory no longer applies? Or could changing the php.ini still be the culprit?
So I understand your question, let me rephrase it and you tell me if I have it correct.
Client fills in resume. Program takes resume and stores it in a TXT file that is sent in email as an attachment to the HR Dept. HR Dept not only gets the resume emails, but also emails that are sent via another form?
If I have it correct: Sounds to me like the email address the resume/TXT file is sent to is also the same address the form mails are sent to. The form is sending to the wrong address. Just edit the .php file and change the address. Should be good to go.
Comments
Did you make sure your smtp server is properly set in PHP? You may have made a typo.
Resolved the errors.
I have another error (though php doesn't gripe because it's not a syntax error) that I'll post later.
I use Courier for my e-mail so I can't verify it will work for most client, but I doubt any of the popular mail clients will have any difficulty with the emails.
[php]
function sendMail() {
if (!isset ($_POST)) { //Oops, forgot your email addy!
die ("<p>Oops! You forgot to fill out the email address! Click on the back arrow to go back</p>");
} else {
$to_name = stripslashes($_POST);
$from_name = stripslashes($_POST);
$subject = stripslashes($_POST);
$body = stripslashes($_POST);
$to_email = $_POST;
$filecount = 0;
foreach($_FILES as $file => $value) {
$attachment[(int)$filecount] = $_FILES[$file];
$attachment_name[(int)$filecount] = $_FILES[$file];
if (is_uploaded_file($attachment[(int)$filecount])) { //Do we have a file uploaded?
$fp = fopen($attachment[(int)$filecount], "rb"); //Open it
$data[(int)$filecount] = fread($fp, filesize($attachment[(int)$filecount])); //Read it
$data[(int)$filecount] = chunk_split(base64_encode($data[(int)$filecount])); //Chunk it up and encode it as base64 so it can emailed
fclose($fp);
$filecount++;
}
}
//Let's start our headers
$headers = "From: $from_name<" . $_POST . ">\n";
$headers .= "Reply-To: <" . $_POST . ">\n";
$headers .= "MIME-Version: 1.0\n";
$headers .= "Content-Type: multipart/related; type=\"multipart/alternative\"; boundary=\"----=MIME_BOUNDRY_main_message\"\n";
$headers .= "X-Sender: $from_name<" . $_POST . ">\n";
$headers .= "X-Mailer: PHP4\n";
$headers .= "X-Priority: 3\n"; //1 = Urgent, 3 = Normal
$headers .= "Return-Path: <" . $_POST . ">\n";
$headers .= "This is a multi-part message in MIME format.\n";
$headers .= "
=MIME_BOUNDRY_main_message \n";
$headers .= "Content-Type: multipart/alternative; boundary=\"----=MIME_BOUNDRY_message_parts\"\n";
$message = "
=MIME_BOUNDRY_message_parts\n";
$message .= "Content-Type: text/plain; charset=\"iso-8859-1\"\n";
$message .= "Content-Transfer-Encoding: quoted-printable\n";
$message .= "\n";
/* Add our message, in this case it's plain text. You could also add HTML by changing the Content-Type to text/html */
$message .= "$body\n";
$message .= "\n";
$message .= "
=MIME_BOUNDRY_message_parts--\n";
$message .= "\n";
for ($i = 0, $filecount = (int) count($data); $i < $filecount; $i++) {
$message .= "
=MIME_BOUNDRY_main_message\n";
$message .= "Content-Type: application/octet-stream;\n\tname=\"" . $attachment_name[$i] . "\"\n";
$message .= "Content-Transfer-Encoding: base64\n";
$message .= "Content-Disposition: attachment;\n\tfilename=\"" . $attachment_name[$i] . "\"\n\n";
$message .= $data[$i]; //The base64 encoded message
$message .= "\n\n";
}
$message .= "
=MIME_BOUNDRY_main_message--\n";
// send the message
mail("$to_name <$to_email>", $subject, $message, $headers);
print "Mail sent. Thank you for using the MyNewName5333 Mailer.";
}
}
[/php]
You'll see some superfluous int casts. If that bothers you, take them out.
I put them in when I got some errors in an attempt to make sure integers were being seen.
1) Most e-mails have no attachments, so they went unused but didn't go without wasting screen space.
2) Sometimes more than 3 attachments are needed.
So, I went digging around and found a way to dynamically alter tables and create INPUT elements. I've taken out the From name and From email because I've hard-coded that in. If you want to have to input that each time then feel free to add that back to the table . . . it's pretty simple to do.
First, you'll need to edit the BODY tag to call a function onLoad.
Here's the form and the script:
Now, all you'll have to do is click on the "Add attachment" button that shows up on the Subject line. Each time the button is clicked another row is added to the table with another file input element. Want 1 attachment? Click the button once. Want 37 attachments? Click it 37 times.
Have fun!
Just like to thank Kwitko for the script first of all and ask a few things about it.
The script works good for me apart from it sends 3 copies of the attachement for some reason? Any idea why?
Also how would i make it that the script will only accept certain extensions? would this help with people sending a malicious script or virus?
thanks again
Al
[PHP]$allowedext = new array('jpg', 'gif', 'png');
$ext = substr($_FILES, strrpos($_FILES, '.') + 1);
if (!in_array($ext, $allowedext)) {
unlink($_FILES);
exit("File type $ext is not allowed.");
}
[/PHP]
You would throw this in before the part that encodes the files to base64.
after which line exactly?
[php]
<?
/* Mailer with Attachments */
$action = $_REQUEST;
global $action;
function showForm() {
?>
<form enctype="multipart/form-data" name="send" method="post" action="<?=$_SERVER?>">
<input type="hidden" name="action" value="send" />
<input type="hidden" name="MAX_FILE_SIZE" value="10000000" />
<p>Recipient Name: <input name="to_name" size="50" /><br />
Recipient Email: <input name="to_email" size="50" /><br />
From Name: <input name="from_name" size="50" /><br />
From Email: <input name="from_email" size="50" /><br />
Subject: <input name="subject" size="50" /><br />
Message: <textarea name="body" rows="10" cols="50"></textarea><br />
Attachment: <input type="file" name="attachment" size="50" /><br />
<input type="submit" value="Send Email" /></p>
<?
}
function sendMail() {
if (!isset ($_POST)) { //Oops, forgot your email addy!
die ("<p>Oops! You forgot to fill out the email address! Click on the back arrow to go back</p>");
}
else {
$to_name = stripslashes($_POST);
$from_name = stripslashes($_POST);
$subject = stripslashes($_POST);
$body = stripslashes($_POST);
$to_email = $_POST;
$attachment = $_FILES;
$attachment_name = $_FILES;
if (is_uploaded_file($attachment)) { //Do we have a file uploaded?
$fp = fopen($attachment, "rb"); //Open it
$data = fread($fp, filesize($attachment)); //Read it
$data = chunk_split(base64_encode($data)); //Chunk it up and encode it as base64 so it can emailed
fclose($fp);
}
//Let's start our headers
$headers = "From: $from_name<" . $_POST . ">\n";
$headers .= "Reply-To: <" . $_POST . ">\n";
$headers .= "MIME-Version: 1.0\n";
$headers .= "Content-Type: multipart/related; type=\"multipart/alternative\"; boundary=\"----=MIME_BOUNDRY_main_message\"\n";
$headers .= "X-Sender: $from_name<" . $_POST . ">\n";
$headers .= "X-Mailer: PHP4\n";
$headers .= "X-Priority: 3\n"; //1 = Urgent, 3 = Normal
$headers .= "Return-Path: <" . $_POST . ">\n";
$headers .= "This is a multi-part message in MIME format.\n";
$headers .= "
=MIME_BOUNDRY_main_message \n";
$headers .= "Content-Type: multipart/alternative; boundary=\"----=MIME_BOUNDRY_message_parts\"\n";
$message = "
=MIME_BOUNDRY_message_parts\n";
$message .= "Content-Type: text/plain; charset=\"iso-8859-1\"\n";
$message .= "Content-Transfer-Encoding: quoted-printable\n";
$message .= "\n";
/* Add our message, in this case it's plain text. You could also add HTML by changing the Content-Type to text/html */
$message .= "$body\n";
$message .= "\n";
$message .= "
=MIME_BOUNDRY_message_parts--\n";
$message .= "\n";
$message .= "
=MIME_BOUNDRY_main_message\n";
$message .= "Content-Type: application/octet-stream;\n\tname=\"" . $attachment_name . "\"\n";
$message .= "Content-Transfer-Encoding: base64\n";
$message .= "Content-Disposition: attachment;\n\tfilename=\"" . $attachment_name . "\"\n\n";
$message .= $data; //The base64 encoded message
$message .= "\n";
$message .= "
=MIME_BOUNDRY_main_message--\n";
// send the message
mail("$to_name<$to_email>", $subject, $message, $headers);
print "Mail sent. Thank you for using the MyNewName5333 Mailer.";
}
}
print <<< EOT
<?xml version="1.0" encoding="iso-8859-1"?>
EOT;?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style="css" type="text/css">
<!--
body {
margin: 0px;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 12px;
}
a {color: #0000ff}
-->
</style>
</head>
<body>
<?
switch ($action) {
case "send":
sendMail();
showForm();
break;
default:
showForm();
}
?>
</body>
</html>
[/php]
that was the same up at the top. It has codes at the bottom that are still there, y is that. Plus it does not do anything when you press send.
I love your code for sending multiple attachments, but when I try to use it, the form works great, but no e-mail is sent?
What do I have to do to fix this? Did I miss something?
Thanks
Wasn't sure if I would get a reply on a 3 year old thread
I'm on it!
I am new to PHP world and I am trying to send mail attachment through your given code. But at the time of sending this mail to @yahoo.com or @gmail.com it's just sending attachment only. No Message with the mail. What should I do now. Also while I am sending this message to POP3 account it's getting done. Problem is with @yahoo.com and all only. Please send me reply asap. It's very urgent.
POP3 = Body & Attachment.
Yahoo! = Attachment only.
GMail = Attachment only.
There is no text in the .dat file
Errors from the "new array" and the $ext code line wasn't getting anything from the code as I tried to print that value.
I placed it just above
[PHP]if (is_uploaded_file($attachment))
{ //Do we have a file uploaded?
$fp = fopen($attachment, "rb"); //Open it
$data = fread($fp, filesize($attachment)); //Read it
$data = chunk_split(base64_encode($data)); //Chunk it up and encode it as base64 so it can emailed
fclose($fp);
}
[/PHP]
Also tried it in between, above the "$data = chunk etc.. part" without much luck.
I was hoping you could explain a bit more how to get this working with the PHP form. The form is working fine for me, except I cannot get this check, which is very important for us.
Thank you.
Thanks!
[php]
function sendMail()
{
if (!isset ($_POST)) { //Oops, forgot your email addy!
die ("<p>Oops! You forgot to fill out the email address! Click on the back arrow to go back</p>");
} else {
$to_name = stripslashes($_POST);
$from_name = stripslashes($_POST);
$subject = stripslashes($_POST);
$body = stripslashes($_POST);
$to_email = $_POST;
//Let's start our headers
$headers = "From: $from_name <" . $_POST . ">\n";
$headers .= "Reply-To: <" . $_POST . ">\n";
$headers .= "MIME-Version: 1.0\n";
$headers .= "Content-Type: multipart/related; type=\"multipart/alternative\"; boundary=\"----=MIME_BOUNDRY_main_message\"\n";
$headers .= "X-Sender: $from_name <" . $_POST . ">\n";
$headers .= "X-Mailer: PHP4\n";
//
//if (checkbox_form.checkbox[counter].checked)
//Return-Receipt-To: x@x.com
//X-Confirm-Reading-To: x@x.com
//Disposition-Notification-To: x@x.com
//
$headers .= "X-Priority: 3\n"; //1 = Urgent, 3 = Normal
$headers .= "Return-Path: <" . $_POST . ">\n";
$headers .= "This is a multi-part message in MIME format.\n";
$headers .= "
=MIME_BOUNDRY_main_message \n";
$headers .= "Content-Type: multipart/alternative; boundary=\"----=MIME_BOUNDRY_message_parts\"\n";
$message = "
=MIME_BOUNDRY_message_parts\n";
$message .= "Content-Type: text/plain; charset=\"iso-8859-1\"\n";
$message .= "Content-Transfer-Encoding: quoted-printable\n";
$message .= "\n";
/* Add our message, in this case it's plain text. You could also add HTML by changing the Content-Type to text/html */
$message .= "$body\n";
$message .= "\n";
$message .= "
=MIME_BOUNDRY_message_parts--\n";
$message .= "\n";
foreach($_FILES as $file => $value) {
$_tmpname = $_FILES[$file];
$_filename = $_FILES[$file];
if (is_uploaded_file($_tmpname)) { //Do we have a file uploaded?
$fp = fopen($_tmpname, "rb"); //Open it
$data = fread($fp, filesize($_tmpname)); //Read it
$data = chunk_split(base64_encode($data)); //Chunk it up and encode it as base64 so it can emailed
$message .= "
=MIME_BOUNDRY_main_message\n";
$message .= "Content-Type: application/octet-stream;\n\tname=\"" . $_filename . "\"\n";
$message .= "Content-Transfer-Encoding: base64\n";
$message .= "Content-Disposition: attachment;\n\tfilename=\"" . $_filename . "\"\n\n";
$message .= $data; //The base64 encoded message
$message .= "\n\n";
fclose($fp);
}
}
$message .= "
=MIME_BOUNDRY_main_message--\n";
// send the message
$ok = mail("$to_name <$to_email>", $subject, $message, $headers);
if ($ok == 1) {
print "Mail sent to $to_name ($to_email).";
} else {
print "Mail did not send. Please press the <b>back</b> button and re-submit the e-mail.";
}
}
}
[/php]
Thanks a million! It works perfectly! Sorry for delayed response, i was not able to answer sooner.
It worked perfectly (and still works on my email account) until they changed their server to an in-house custom built server.
So I got a call syaing they were'nt recieveing the emails at all. I changed the code to my email address and it works fine, so how could they not be recieving emails?
On previous posts that dealt with this the response was to change their php.ini file...how would I access that and what would I change?
Thanks!
I sent my network guy an email and he's gonna look into that.
Here's another interesting piece of the puzzle. Another web developer here (who recently left) wrote a form that submits a resume as a .txt so it can be entered into an Access DB via a parsing program. (The client had already paid for the access databse, so we couldn't get them to switch to MySQL)
So the client fills in the resume & submits the form, which creates a .txt file and sends it to their HR department as an attachment in an email...Now supposedly they are getting these emails!? Does this mean that the above theory no longer applies? Or could changing the php.ini still be the culprit?
Thanks man.
Client fills in resume. Program takes resume and stores it in a TXT file that is sent in email as an attachment to the HR Dept. HR Dept not only gets the resume emails, but also emails that are sent via another form?
If I have it correct: Sounds to me like the email address the resume/TXT file is sent to is also the same address the form mails are sent to. The form is sending to the wrong address. Just edit the .php file and change the address. Should be good to go.