Trying to send csv attachment AND body text in email - php

I have been able to write php script (with HTML) to $_REQUEST online form data entry and either
(1) write to a CSV and email it as an attachment, or
(2) include data in the body of any email.
But I cannot do both at the same time. I want the CSV for quick import into database, and I want email body to also include the details so the shipping dept has a pick list for packing. How do I get both features to work simultaneously without interfering with each other?
Thank you in advance.
PHP SCRIPT
$to = "name#domain.com";
$subject = "Order - " . $_Tech_Name;
//Add the headers
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
$headers = "MIME-Version: 1.0\n" .
"From: {$email_from}\n" .
"Content-Type: multipart/mixed;\n" .
" boundary=\"{$mime_boundary}\"";
// email body includes only fields not null
$body = "";
foreach ($_REQUEST as $Field=>$Value) {
if($Value != ''){
$body .= "$Field: $Value\n\n";
}
}
$email_body = "Here are the details: \n\n $body";
// csv file name format
$today = date("m.d.y");
$csv_name = "order - " . $_Tech_Name . " " . $today . ".csv";
$fp = fopen($csv_name,'a');
fwrite($fp,$data);
fclose($fp);
$attachments[] = Array(
'data' => $data,
'name' => $csv_name,
'type' => 'application/vnd.ms-excel'
);
//Add sttachments
foreach($attachments as $attachment){
$data = chunk_split(base64_encode($attachment['data']));
$name = $attachment['name'];
$type = $attachment['type'];
$message .=
"--{$mime_boundary}\n" .
"Content-Type: {$type};\n" .
" name=\"{$name}\"\n" .
"Content-Transfer-Encoding: base64\n\n" .
$data . "\n\n" ;
}
**PHP SCRIPT - I have isolated the problem with the following additional script that is part of the script shown above, but I do not as yet understand why it is a problem. By commenting out either $message (attachment) or $email_body (body only) I am able to get one or the other to work. But if I leave both variables in there, then neither works **
mail(
$to,
$subject,
$message, // for attachment only
// $email_body, // for body only
$headers
);

By isolating the problem in my original post I was able to get it to work by writing two (2) "mail" commands as follows:
// attachment
mail($to, $subject, $message, $headers);
// body
mail($to, $subject, $email_body, $headers);
I am happy with this solution, but if someone can find a way to get the same email to include the body content and attach a CSV, that would be ideal.

Related

php generated email with csv attachment - sending extra (incorrect) version

I am a complete novice with php, so forgive me if this is something very obvious! I have tried to create an html form on my website which, when submitted, generates an email with a csv attachement which is sent to me with the relevant information.
I have been using code found online (some from this forum) to try to create a solution and seem to be vey close - however there is a problem somewhere. I am receiving 2 emails when submitted - the first is incorrect in that it is missing the senders' email address and the csv has no information - the second email is exactly right however.
This is the code I am using:
<?php
$email=$_POST['email'];
$customer=$_POST['customer'];
$quantity=$_POST['quantity'];
$prefix=$_POST['prefix'];
$itemno=$_POST['itemno'];
$format=$_POST['format'];
$to = "me#myemail.com";
$subject = "Form 01";
//Message Body
$text = "Form 01 attached";
//The Attachment
$cr = "\n";
$data .= "$email" . $cr;
$data .= "$customer" . $cr;
$data .= "$quantity" . $cr;
$data .= "$prefix" . $cr;
$data .= "$itemno" . $cr;
$data .= "$format" . $cr;
$fp = fopen('form01.csv','a');
fwrite($fp,$data);
fclose($fp);
$attachments[] = Array(
'data' => $data,
'name' => 'form_01.csv',
'type' => 'application/vnd.ms-excel'
);
//Generate a boundary string
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
//Add the headers for a file attachment
$headers = "MIME-Version: 1.0\n" .
"From: {$from}\n" .
"Content-Type: multipart/mixed;\n" .
" boundary=\"{$mime_boundary}\"";
//Add a multipart boundary above the plain message
$message = "This is a multi-part message in MIME format.\n\n" .
"--{$mime_boundary}\n" .
"Content-Type: text/html; charset=\"iso-8859-1\"\n" .
"Content-Transfer-Encoding: 7bit\n\n" .
$text . "\n\n";
//Add attachments
foreach($attachments as $attachment){
$data = chunk_split(base64_encode($attachment['data']));
$name = $attachment['name'];
$type = $attachment['type'];
$message .= "--{$mime_boundary}\n" .
"Content-Type: {$type};\n" .
" name=\"{$name}\"\n" .
"Content-Transfer-Encoding: base64\n\n" .
$data . "\n\n" ;
}
$message .= "--{$mime_boundary}--\n";
mail($to, $subject, $message, $headers);
?>
I am also trying to add in reCaptcha, this is going in fine except it only seems to be allowing the first email to get through - which is the incorrect one. So I hope if the problem is in the code above and it can be fixed, then this should be solved too.
Thanks in advance!
The code you are giving us is (I guess) incomplete. It is (obviously) not the complete HTML page. I guess this PHP script is at the top of your HTML page right above your form. Am I right?
So when you open the page your PHP script sends the first (empty) email. After the form is submitted and your $_POST array is filed with data the second (and correct) email will be sent.
To fix this you must check if the $_POST array is not empty:
<?php
if (!empty($_POST["email"])) {
//your code here
}
?>
Like this here: If isset $_POST

Php mail not working with more than one recipient

How come this piece of php code doesn't work with multiple recipient ?
It only works if $to has only one adress, like:
$to = 'aa#bb.com';
Edit
It works if email adresses are on the same domain.. For instance, if the website is www.example.com, emails such as xxx#example.com will work but yyy#other.com won't.
Solution
PHPMailer. It gives an easy way to configure SMTP.
Here is the initial code
<?php
//define the receiver of the email
$to = 'aa#bb.com, cc#dd.com, ee#ff.com';
// array with filenames to be sent as attachment
$files = array("a.zip","b.c","a.html");
// email fields: to, from, subject, and so on
$from = "mail#mail.com";
$subject ="My subject";
$message = "My message";
// boundary
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
// headers for attachment
$headers = "From: $from";
$headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\"";
// multipart boundary
$message = "This is a multi-part message in MIME format.\n\n" . "--{$mime_boundary}\n" . "Content-Type: text/plain; charset=\"iso-8859-1\"\n" . "Content-Transfer-Encoding: 7bit\n\n" . $message . "\n\n";
$message .= "--{$mime_boundary}\n";
// preparing attachments
for($x=0;$x<count($files);$x++){
$file = fopen($files[$x],"rb");
$data = fread($file,filesize($files[$x]));
fclose($file);
$data = chunk_split(base64_encode($data));
$message .= "Content-Type: {\"application/octet-stream\"};\n" . " name=\"$files[$x]\"\n" .
"Content-Disposition: attachment;\n" . " filename=\"$files[$x]\"\n" .
"Content-Transfer-Encoding: base64\n\n" . $data . "\n\n";
$message .= "--{$mime_boundary}\n";
}
// send
$ok = #mail($to, $subject, $message, $headers);
if ($ok) {
echo "<p>mail sent to $to!</p>";
} else {
echo "<p>mail could not be sent!</p>";
}
?>
Here is the final code
// PHPMailer
$mail = new PHPMailer;
// setting up PHPMailer
$mail->isSMTP();
$mail->Host = 'host.com';
$mail->SMTPAuth = false;
$mail->Port = xx;
$mail->setFrom($_POST['email'], $_POST['name']);
$mail->Subject = $_POST['subject'];
$mail->msgHTML($_POST['message']);
foreach($contacts as $contact)
$mail->addAddress($contact['email']);
// If the user has attached some files
foreach ($_FILES as $file)
$mail->addAttachment($file['tmp_name'], basename($file['name']));
$response = array("status" => $mail->send() ? "sent" : "error");
echo json_encode($response);
You need use proper RFC 2822 formating.
Don't use # because you don't know what is the error. If you format mails in format "user#example.com, anotheruser#example.com" it's correct and you need search problem elsewhere.
You can also see example #4 on http://php.net/manual/en/function.mail.php#example-3493 page.
although this is not a direct response to your issue, you could potentially save yourself trouble by using a pre-existing email sending library like either:
phpmailer
https://github.com/PHPMailer/PHPMailer
or simplesmtp
https://bitbucket.org/ghorwood/simplesmtp/

mail send but its empty in php

i want to send mail and mail is going to send but problem is that mail is empty in mail box. What is the problem in my code?
$afile = $_FILES['myFile'];
//Getting info about above taken file
$fileatttype = $afile['type'];
$fileattname = $afile['name'];
$filesize=$afile['size'];
if($fileatttype=="application/octet-stream" or $fileatttype=="text/plain" or $fileatttype=="application/msword" or $fileatttype=="application/pdf")
{
$otherData="**********************Personal Details*********************\n
Position Applied For :$Position\n
First Name :$First\n
Last Name:$LastName\n
Date Of Birth :$DD-$MM-$yy\n
Correspondence Address :$Caddress1 $Caddress2 $Caddress2\n
Permanent Address :$Paddress1 $Paddress2 $Paddress2\n
Contact No(HOME):$Home\n
Mobile :$Mobile\n
E-Mail :$EMail\n
**********************Education*********************\n
Quallification :$Quallification\n
OtherCourse:$OtherCourse\n
**********************Previous Working Details*********************\n
Company Name-$WCompany1\n
Title-$WTitle1\n
CTC-$WCTC1\n
Reasons of Leaving-$WReason1\n
Company Name-$WCompany2\n
Title-$WTitle2\n
CTC-$WCTC2\n
Reasons of Leaving-$WReason2\n
Company Name-$WCompany3\n
Title-$WTitle3\n
CTC-$WCTC3\n
Reasons of Leaving-$WReason3\n
Company Name-$WCompany4\n
Title-$WTitle4\n
CTC-$WCTC4\n
Reasons of Leaving-$WReason4\n
Current CTC:$CCTC\n
Expected CTC:$ECTC\n
Notice Period Required :$NoticePeriod\n
Total no of years experience :$TotalExperience Years\n
Current Location :$Clocation\n
Preferred Location:$Plocation\n
Resume:$Resume\n
**********************Family Details*********************\n
Father / Guardian Name :$Fname\n
Father / Spouse: Occupation:$Focc\n
Kids:$Kids\n
Age of Kids:$AOK\n
";
$to="renu_activa#yahoo.co.in";
$from=$_POST['First'];
$subject=$Position;
$headers = "From: $First";
if($filesize>0)
{
$file = fopen($afile['tmp_name'],'rb');
$data = fread($file,$afile['size']);
fclose( $file );
}
//Making a random number to use afterwards with help of current time
$semi_rand = md5( time() );
//Defining the type of email as Mime email
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
//Appending to headers, telling that its multipart message with text and attachment
$headers .= "\nMIME-Version: 1.0\n" .
"Content-Type: multipart/mixed;\n" .
" boundary=\"{$mime_boundary}\"";
//The text part of message in variable $otherData with other details
$message = "This is a multi-part message in MIME format.\n\n" .
"--{$mime_boundary}\n" .
"Content-Type: text/plain; charset=\"iso-8859-1\"\n" .
"Content-Transfer-Encoding: 7bit\n\n" .
$otherData . "\n\n";
//Encoding all the data read from file to "base64" the standard for email attachments
$data = chunk_split(base64_encode($data));
//Appending the file data to the email including the file name etc
$message .= "--{$mime_boundary}\n" .
"Content-Type: {$fileatttype};\n" .
" name=\"{$fileattname}\"\n" .
"Content-Disposition: attachment;\n" .
" filename=\"{$fileattname}\"\n" .
"Content-Transfer-Encoding: base64\n\n" .
$data . "\n\n" .
"--{$mime_boundary}--\n";
$sentmail=mail($to, $subject, $message, $headers);
if($sentmail)
{
header('location: career-with-us.php');
}
else
{
echo "Mail Not Send Successfully....";
}
}
else
{
echo "Wrong format: Please upload only PDF/DOC/DOCX/TXT file format...";
}
I am not getting why its empty neither textbox value nor file attachment is showing in mail. Its totally empty.
You define a new variable for the body of the email.
$mess = 'Please check it';
$messa = '*****...
I'm assuming you meant
$mess = 'Please check it';
$mess .= '*****...

Attach file from the server into email

can anyone give me some idea how to attach a file from the server and send it as attachment through email??
i have the following code:
<?php
// Read POST request params into global vars
$to = $_POST['to'];
$from = $_POST['from'];
$subject = $_POST['subject'];
$message = $_POST['message'];
// Obtain file upload vars
$fileatt = $_FILES['fileatt']['tmp_name'];
$fileatt_type = $_FILES['fileatt']['type'];
$fileatt_name = $_FILES['fileatt']['name'];
$headers = "From: $from";
if (is_uploaded_file($fileatt)) {
// Read the file to be attached ('rb' = read binary)
$file = fopen($fileatt,'rb');
$data = fread($file,filesize($fileatt));
fclose($file);
// Generate a boundary string
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
// Add the headers for a file attachment
$headers .= "\nMIME-Version: 1.0\n" .
"Content-Type: multipart/mixed;\n" .
" boundary=\"{$mime_boundary}\"";
// Add a multipart boundary above the plain message
$message = "This is a multi-part message in MIME format.\n\n" .
"--{$mime_boundary}\n" .
"Content-Type: text/plain; charset=\"iso-8859-1\"\n" .
"Content-Transfer-Encoding: 7bit\n\n" .
$message . "\n\n";
// Base64 encode the file data
// Add file attachment to the message
$message .= "--{$mime_boundary}\n" .
"Content-Type: {$fileatt_type};\n" .
" name=\"{$fileatt_name}\"\n" .
//"Content-Disposition: attachment;\n" .
//" filename=\"{$fileatt_name}\"\n" .
"Content-Transfer-Encoding: base64\n\n" .
$data . "\n\n" . "--{$mime_boundary}--\n";
}
// Send the message
$ok = #mail($to, $subject, $message, $headers);
if ($ok) {
echo "<p>Mail sent! Yay PHP!</p>";
} else {
echo "<p>Mail could not be sent. Sorry!</p>";
}
?>
but this code does not attach file from the server.
please help me out.. thanks in advance..!!
One question: Do you want to send e-mails with attachment or do you want to improve your PHP skills with this problem?
If you only want to send mails, have a look at PHPMailer which is very good and easily to handle. For myself I'm using this for years without problems.
For improving your skills: You say that the attachment is encoded in base64, but I cannot find the line where you do something like $data = base64_encode($data); You add the $data of your attachment in plain to the mail.

PHP mass mail script shows extra file in outlook

I use PHP script to send email with multiple attachments, it works great for gmail, but in Microsoft Outlook i also see blank file ATT00010.txt (random numbers.) as attachment. And when i send email from outlook with multiple attachments as well it does not show no file like this.
I echo'ed output from email script and there is no such file in code. Can someone tell me how to remove this file from outlook?
Email script is below.
// array with filenames to be sent as attachment
$files = array("file_1.ext","file_2.ext","file_3.ext",......);
// email fields: to, from, subject, and so on
$to = "mail#mail.com";
$from = "mail#mail.com";
$subject ="My subject";
$message = "My message";
$headers = "From: $from";
// boundary
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
// headers for attachment
$headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\"";
// multipart boundary
$message = "This is a multi-part message in MIME format.\n\n" . "--{$mime_boundary}\n" . "Content-Type: text/plain; charset=\"iso-8859-1\"\n" . "Content-Transfer-Encoding: 7bit\n\n" . $message . "\n\n";
$message .= "--{$mime_boundary}\n";
// preparing attachments
for($x=0;$x<count($files);$x++){
$file = fopen($files[$x],"rb");
$data = fread($file,filesize($files[$x]));
fclose($file);
$data = chunk_split(base64_encode($data));
$message .= "Content-Type: {\"application/octet-stream\"};\n" . " name=\"$files[$x]\"\n" .
"Content-Disposition: attachment;\n" . " filename=\"$files[$x]\"\n" .
"Content-Transfer-Encoding: base64\n\n" . $data . "\n\n";
$message .= "--{$mime_boundary}\n";
}
// send
$ok = #mail($to, $subject, $message, $headers);
if ($ok) {
echo "<p>mail sent to $to!</p>";
} else {
echo "<p>mail could not be sent!</p>";
}
If you want something that's a little less of a pain to use and send attachments with, try Swift Mailer. (swiftmailer.org) I've been using it in my projects and it works great.
Here's an example:
$message = Swift_Message::newInstance()
->setSubject('Webinar Registration')
->setFrom(array('replyto#example.org' => 'From Name'))
->setTo(array('destination#example.org'))
->setBody($MESSAGE_TEXT)
;
$message->attach(Swift_Attachment::fromPath('SOME_FILE_PATH'));
$transport = Swift_SmtpTransport::newInstance('127.0.0.1', 25);
$mailer = Swift_Mailer::newInstance($transport);
$result = $mailer->send($message);
Just my two cents.
Otherwise, I was going to mention what someone else already beat me to -- check the boundaries.
The last boundary line in a multipart/* message must have -- appended at the end, in addition to what all of the other boundary lines have. A consumer can use that to recognize the end of a message.
Apparently Outlook treats the absence of the correct ending as an indication that the message has been truncated, and then does the best it can to display whatever it did receive.
Its my second account, i actually found solution and don't need no library or class at all although i might turn this into class and add some stuff, its always better to have full understanding of process not just from, to, files etc fields.
Solution is simple here just replace last part with
if ($x == count($files)-1)
$message .= "--{$mime_boundary}--\r\n";
else
$message .= "--{$mime_boundary}\n";
\r is not necessary
if you just put -- it will use it many times inside loop IF checks if this is last loop.

Categories