php 如何从字符串发送带有 CSV 附件的电子邮件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10334753/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to send an email with a CSV attachment from a string
提问by Alex L
Here is my attempt at it can you let me know what I am doing wrong?
这是我的尝试,你能告诉我我做错了什么吗?
allputcsv converts the array into a csv formatted string. That is then base64 encoded and chunk split, this seems to work for normal files but is there something different I should do because I am using a string?
allputcsv 将数组转换为 csv 格式的字符串。然后是 base64 编码和块分割,这似乎适用于普通文件,但是我应该做些什么不同的事情,因为我使用的是字符串?
<?php
function sputcsv($row, $delimiter = ',', $enclosure = '"', $eol = "\n")
{
static $fp = false;
if ($fp === false)
{
$fp = fopen('php://temp', 'r+');
}
else
{
rewind($fp);
}
if (fputcsv($fp, $row, $delimiter, $enclosure) === false)
{
return false;
}
rewind($fp);
$csv = fgets($fp);
if ($eol != PHP_EOL)
{
$csv = substr($csv, 0, (0 - strlen(PHP_EOL))) . $eol;
}
return $csv;
}
function allputcsv($arr) {
$str = "";
foreach($arr as $val) {
$str .= sputcsv($val);
}
return $str;
}
function send_mail($arr) {
$to = '[email protected]';
$subject = 'Test email with attachment';
$random_hash = md5(date('r', time()));
$headers = "From: [email protected]\r\nReply-To: [email protected]";
$headers .= "\r\nContent-Type: multipart/mixed; boundary=\"--".$random_hash."\"";
$attachment = chunk_split(base64_encode(allputcsv($arr)));
ob_start();
?>
--<?php echo $random_hash; ?>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Hello World!!!
This is simple text email message.
--<?php echo $random_hash; ?>
Content-Type: application/vnd.ms-excel;
name="test.csv"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="test.csv"
<?php echo $attachment; ?>
--<?php echo $random_hash; ?>--
<?php
$message = ob_get_clean();
$mail_sent = @mail( $to, $subject, $message, $headers );
}
$array = array(array(1,2,3,4,5,6,7),array(1,2,3,4,5,6,7),array(1,2,3,4,5,6,7));
send_mail($array);
?>
Notes: I have to use the mail function I don't have a choice (I could use a wrapper but I would prefer not to) and I cant save the file on the server side.
注意:我必须使用邮件功能,我别无选择(我可以使用包装器,但我不想这样做)并且我无法将文件保存在服务器端。
回答by DaveRandom
You can wrap the CSV creation code into a single function easily in a much shorter and more efficient way.
您可以以更短、更有效的方式轻松地将 CSV 创建代码包装到单个函数中。
The correct MIME type for CSV files is text/csv. Also, you should use string concatenation and explicit \r\nsequences, since RFCs call for CRLF line separations and by using heredoc/nowdoc/output buffering with literal new lines, you will end up with 2 problems:
CSV 文件的正确 MIME 类型是text/csv. 此外,您应该使用字符串连接和显式\r\n序列,因为 RFC 要求 CRLF 行分隔,并且通过使用带有文字新行的 heredoc/nowdoc/output 缓冲,您最终会遇到两个问题:
- Your indentation may screw up the message format
- Copying the file via FTP in ASCII mode may break the line endings
- 您的缩进可能会破坏消息格式
- 在 ASCII 模式下通过 FTP 复制文件可能会破坏行尾
Try this instead:
试试这个:
function create_csv_string($data) {
// Open temp file pointer
if (!$fp = fopen('php://temp', 'w+')) return FALSE;
// Loop data and write to file pointer
foreach ($data as $line) fputcsv($fp, $line);
// Place stream pointer at beginning
rewind($fp);
// Return the data
return stream_get_contents($fp);
}
function send_csv_mail ($csvData, $body, $to = '[email protected]', $subject = 'Test email with attachment', $from = '[email protected]') {
// This will provide plenty adequate entropy
$multipartSep = '-----'.md5(time()).'-----';
// Arrays are much more readable
$headers = array(
"From: $from",
"Reply-To: $from",
"Content-Type: multipart/mixed; boundary=\"$multipartSep\""
);
// Make the attachment
$attachment = chunk_split(base64_encode(create_csv_string($csvData)));
// Make the body of the message
$body = "--$multipartSep\r\n"
. "Content-Type: text/plain; charset=ISO-8859-1; format=flowed\r\n"
. "Content-Transfer-Encoding: 7bit\r\n"
. "\r\n"
. "$body\r\n"
. "--$multipartSep\r\n"
. "Content-Type: text/csv\r\n"
. "Content-Transfer-Encoding: base64\r\n"
. "Content-Disposition: attachment; filename=\"file.csv\"\r\n"
. "\r\n"
. "$attachment\r\n"
. "--$multipartSep--";
// Send the email, return the result
return @mail($to, $subject, $body, implode("\r\n", $headers));
}
$array = array(array(1,2,3,4,5,6,7), array(1,2,3,4,5,6,7), array(1,2,3,4,5,6,7));
send_csv_mail($array, "Hello World!!!\r\n This is simple text email message.");
回答by Mike Volmar
This is a simpler solution to create the csv I use to email attachments with phpmailer.
这是创建用于使用 phpmailer 发送电子邮件附件的 csv 的更简单的解决方案。
$csvinfo .= "$row[0],$row[1],$row[2],$row[3]\n";
$attachment = "details.csv";
file_put_contents($attachment, $csvinfo, LOCK_EX);
and the relevant phpmailer lines to send an email with attachment
和相关的 phpmailer 行发送带有附件的电子邮件
$mail = new PHPMailer;
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'x'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'xx'; // SMTP username
$mail->Password = 'xx'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable TLS or SSL also accepted
$mail->Port = 587; // TCP port to connect to
$mail->setFrom('[email protected]', 'Lily');
$mail->AddAddress("[email protected]");
$mail->addAttachment($attachment); // Add attachments
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = "Report";
$mail->Body = $message;
if(!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent';
}
回答by TechyFlick
You can try this code. It works perfect.
你可以试试这个代码。它完美无缺。
<?php
$con = mysqli_connect('localhost', 'username', 'password', 'databasename');
if (!$con)
{
die("error" . mysqli_connect_error());
}
error_reporting(E_ERROR);
$filename = "menu_list";
$sql = mysqli_query($con, "SELECT * FROM menu_list");
$row = mysqli_fetch_assoc($sql);
$filename2='datas/'.$filename.'.csv';
$fp = fopen($filename2, "w");
$seperator = "";
$comma = "";
foreach ($row as $name => $value){$seperator .= $comma . '' . str_replace('', '""', $name);$comma = ",";}
$seperator .= "\n";
$seperator;
fputs($fp, $seperator);
mysqli_data_seek($sql, 0);
while ($row = mysqli_fetch_assoc($sql))
{
$seperator = "";
$comma = "";
foreach ($row as $name => $value){$seperator .= $comma . '' . str_replace('', '""', $value);$comma = ",";}
$seperator .= "\n";
fputs($fp, $seperator);
}
fclose($fp);
$my_file = $filename2;
$path = "datas/";
$from_name = "solomon";
$from_mail = "[email protected]";
$mailto = "[email protected]";
$subject = "This is a mail with attachment.";
$message = "Hi,\r\n do you got attachment?\r\n\r\Solomon";
$replyto = "[email protected]";
$file = $my_file;
$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=\"" . $filename2 . "\"\r\n";
$header .= "Content-Transfer-Encoding: base64\r\n";
$header .= "Content-Disposition: attachment; filename=\"" . $filename2 . "\"\r\n\r\n";
$header .= $content . "\r\n\r\n";
$header .= "--" . $uid . "--";
mail($mailto, $subject, "", $header)
?>

