PHP生成的CSV附件似乎通过Outlook而不是Gmail丢失了第一行的一部分


PHP Generated CSV attachment seems to lose part of first line via Outlook but not Gmail

我有一个PHP脚本在FreeBSD 8.0, sendmail, PHP 5.2.11 (cli)下通过cron运行。

CSV的第一行由这行定义:

$content .= "'n" .  'first_name,last_name,address1,address2,city,state_province,postal_code,country' . "'n";

在移动到当前服务器之前,这个脚本工作得很好,但是现在它有一个小故障:

如果电子邮件是通过Outlook收到的,第一行在Excel中看起来像这样:

ate_province    postal_code country

和这个在文本编辑器:

ate_province,postal_code,country

我在开头添加了一个额外的"'n",看到它在缩短的字符串中增加了一个字符,所以我尝试添加31,果然Outlook,我的文本编辑器和Excel看到了一个完美的文件。

然后我登录到Gmail并下载了应该是完全相同的文件,因为它是完全相同的电子邮件。我在Excel和我的文本编辑器中打开它,我应该找到什么,但31个换行…

有人对发生了什么有什么建议吗?

//每个请求链接到邮件头http://pastebin.com/wuyVf9HP

//编辑根据XzKto的请求添加整个邮件例程

if (fwrite($handle, $content) === FALSE) {
  die("Cannot write to file ($filename)");
}
$message = "Here is the file (comma-separated values) of addresses for'n";
$message .= $pm_row['title'] . " Requests ($now_YmdHMS).'n'n";
$data_email = $pm_row['fulfillment_data_email'];
$data_email_cc = "$pm_row[fulfillment_data_email_cc],$developer_email";
$subject = $pm_row['title'] . " Requests ($now_YmdHMS)";
$random_hash = md5(date('r', time()));
$headers = "From: xxxx <tourism@xxx.org>'r'nReply-To: tourism@xxx.org'r'nCc:$data_email_cc"; 
$headers .= "'nContent-Type: multipart/mixed; boundary='"PHP-mixed-".$random_hash."'"";
$attachment = chunk_split(base64_encode(file_get_contents($filename)));
$output = "
--PHP-mixed-$random_hash; 
Content-Type: multipart/alternative; boundary='PHP-alt-$random_hash'
--PHP-alt-$random_hash
Content-Type: text/plain; charset='iso-8859-1'
Content-Transfer-Encoding: 7bit
$message
--PHP-alt-$random_hash 
Content-Type: text/html; charset='iso-8859-1'
Content-Transfer-Encoding: 7bit
$message
--PHP-alt-$random_hash--
--PHP-mixed-$random_hash
Content-Type: application/zip; name=$now_YmdHMS.$pm_row[handle].csv
Content-Transfer-Encoding: base64 
Content-Disposition: attachment 
$attachment
--PHP-mixed-$random_hash--";
mail($data_email, $subject, $output, $headers);

不确定这是否会解决问题,但我的建议是尝试使用fputcsv而不是手工构建CSV文件。

的用法如下:

$fp = fopen('output.csv', 'w');
$fields = array('first_name', 'last_name', 'address1', .....);
$rows = func_that_returns_data();
fputcsv($fp, $fields);
foreach ($rows as $row) {
    fputcsv($fp, $row);
}