【发布时间】:2016-08-03 04:38:31
【问题描述】:
我在几个脚本中遇到了一些非常特殊的 UTF-8 行为,这些脚本通过 CSV 文件将信息导入/导出到数据库,尤其是 Excel 处理它们的方式。
脚本本身并不是特别复杂,我相信我正确设置了编码(为简洁起见,我排除了错误处理和字符转义代码):
导入
header("Content-Type: text/plain; charset=UTF-8");
require_once("inc.db.php"); // database connection
mysql_query("SET NAMES utf8");
$csv = $_FILES['csv'];
$handle = fopen($csv['tmp_name'], "r");
while ($data = fgetcsv($handle, 1000, ',', '"')) {
$first_name = $data[0];
$family_name = $data[1];
$company = $data[2];
mysql_query("INSERT INTO table SET first_name = '$first_name', etc...);
}
导出
header("Content-Type: text/csv; charset=UTF-8");
header("Content-Disposition: attachment; filename=file.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo "\xEF\xBB\xBF"); // utf-8 bom
setlocale(LC_ALL, "en_US.UTF8");
require_once("inc.db.php"); // database connection
mysql_query("SET NAMES utf8");
echo "FIRST NAME,FAMILY NAME,COMPANY,\n";
$query = mysql_query("SELECT first_name, family_name, company FROM table");
while ($data = mysql_fetch_assoc($query)) {
echo '"' . $first_name . '","' . $family_name. '","' . $company. '",\n';
}
// Alternate attempt at looping below
$array = array();
while ($data = mysql_fetch_assoc($query)) {
$array[] = $data;
}
$x = fopen("php://output", "w");
foreach ($array as $fields) {
fputcsv($x, $fields);
}
fclose($x);
在我看来,这两个脚本都运行良好,到目前为止没有问题。然而,当我在 Excel 中打开并处理导出的 CSV 文件时,有趣的事情就从这里开始了。
数据库中的信息包含外来拉丁字符,如é 和Ü。这些存储正确(MySQL数据库编码为utf8_unicode_ci),仍然没有问题。
但是,这三个方案中只有两个可以正常工作。但是你猜怎么着,不工作的那个(场景二)是我需要工作的那个……不总是这样吗?
场景一
我导出一个 CSV 文件,然后立即重新导入。我从不以任何方式打开或修改文件。
不幸的是,这是一个毫无意义的练习。不过,它确实有效。
场景二
我导出一个 CSV 文件,打开它,修改内容,保存,然后重新导入。
有趣的提示:当我从 Excel 的对话框菜单中选择“保存”时,它会保存为“Unicode 文本”文件,而不是覆盖 CSV 文件。此新文件仍可在 Excel 中打开,但数据已损坏。我需要选择“另存为...”并从文件类型菜单中选择“逗号分隔值”。我也尝试在这一步的编码菜单中选择 UTF-8。
这种情况的问题在于外来字符:一旦导入脚本到达其中一个,它就会停止将该字段写入数据库。没有损坏的字符â€。没有小问号�。简单地说,什么都没有。但是,CSV 的那一行中的其余数据写得很好。
场景三
我导出一个 CSV 文件,打开它,修改内容,保存,在文本编辑器中打开,使用 UTF-8 编码重新保存,然后重新导入。
万岁,它有效!但是,我不能指望这个系统的用户使用文本编辑器和编码——他们应该能够无缝地导出 > 编辑 > 保存 > 导入。
我对出了什么问题的看法™
- 我的一个脚本(可能是导入)中的某些内容未正确处理编码。
- 我的一个脚本(可能是导出)中的某些内容未正确创建 CSV 文件,因此保存对话框中的 Unicode 文本文件类型。
- Excel 只是真的不喜欢 UTF-8 文件,我无能为力。
请告诉我这是我的错,我有办法解决这个问题!
【问题讨论】:
-
您是在 Mac 还是 Windows 上使用 Excel?我知道与使用不同编码的 Windows 相比,Mac 上的 Excel 存在一些问题。
-
这是在 Windows、Office 2010 和 2013 上。
标签: php excel csv encoding utf-8