Php 带BOM的UTF-16LE编码

Php 带BOM的UTF-16LE编码,php,export-to-csv,utf-16le,Php,Export To Csv,Utf 16le,我正在从事一个使用各种特殊字符的项目,目前我正在专门处理阿拉伯语字符,我正在努力使它们在从PHP导出时正确显示在Excel中,使用我的代码,就像它们在导出文件中显示为方括号一样 我尝试了许多不同的方法来实现这一点,有些方法比其他方法效果更好,但最终每一次尝试都有某种形式的问题 我做了一些研究,发现使用BOM编码为UTF-16LE是最有可能实现这一点的方法,但到目前为止,我还无法确定如何最好地实现这一点 我试过的 您可以在下面的代码中看到,根据我在代码开始时设置的四个变量,我有几个代码可以采用的

我正在从事一个使用各种特殊字符的项目,目前我正在专门处理阿拉伯语字符,我正在努力使它们在从PHP导出时正确显示在Excel中,使用我的代码,就像它们在导出文件中显示为方括号一样

我尝试了许多不同的方法来实现这一点,有些方法比其他方法效果更好,但最终每一次尝试都有某种形式的问题

我做了一些研究,发现使用BOM编码为UTF-16LE是最有可能实现这一点的方法,但到目前为止,我还无法确定如何最好地实现这一点


我试过的 您可以在下面的代码中看到,根据我在代码开始时设置的四个变量,我有几个代码可以采用的路径。我开始设置这些切换,以便我可以尝试不同的方法,而不会使代码太难阅读

目前,通过代码中的设置,我可以导出CSV,但阿拉伯字符显示为方形框-当我在VS代码中查看CSV时,我可以看到它无法识别编码类型,将默认为UTF-8,它还将告诉我它已成功导出BOM

切换到UTF-16LE似乎很简单,我实际上已经成功了,但自从将其导出为BOM后,我一直无法确定如何将其返回到UTF-16LE。最终,我认为我已经盯着代码看了太久,我怀疑修复会很快,但我现在无法看到它,我希望通过在上的一个问题中解释我的问题,以便我能够找出问题是什么,但到目前为止什么都没有

我曾尝试使用
array\u walk
iconv
mb\u convert\u encode
将值转换为UTF-16LE,我尝试使用
\xEF\xBB\xBF
chr(255)在标题中设置内容编码和内容类型。chr(254)
在导出开始时转换为BOM(下面的当前版本似乎工作得最好)

您还可以在我的代码中看到,我同时使用了
fwrite
fputcsv
来查看哪一个效果最好,
fputcsv
目前似乎效果最好

任何提示都将不胜感激-任何需要的澄清请在评论中提出


到目前为止我的代码
生成的文件是否有效UTF-16…?你到底在努力解决什么问题?作为一般建议,我会说:众所周知,Excel的编码非常糟糕,唯一真正安全的方法是生成XLSX文件,而不是CSV文件。由于VS code无法识别编码类型,并且默认为UTF-8,因此我不认为它是有效的UTF-16。主要的问题是字符在CSV中以方括号的形式出现(有时在我的代码中使用不同的路径,通过调整它们以中文符号的形式出现的变量)。我会使用XLSV,但这是一个设置为读取CSV的导入/导出系统,我不确定在调整导入脚本以使用XLSV方面我有多少余地。要测试文件的编码方式,请使用文本编辑器打开它,并指定编辑器应以UTF-16LE打开它。如果角色看起来不错,那就没问题了。要进行更严格的测试,请在十六进制编辑器中打开它,手动检查字节是否符合预期字符的正确编码。至于回旋余地……那么,此导出的目的是什么?如果它被定义为必须导出CSV,那么它的预期编码可能也被定义了?那么您就不必特别担心Excel的兼容性了。如果您确实希望提供一个保证在Excel中正常工作的文件,那么您很难避免专门提供XLSX文件。使用正确的编码将CSV导入Excel是一场噩梦。您可以考虑用PHPOffics/PHPSPEDABLE创建真正的Excel文件吗?你到底在努力解决什么问题?作为一般建议,我会说:众所周知,Excel的编码非常糟糕,唯一真正安全的方法是生成XLSX文件,而不是CSV文件。由于VS code无法识别编码类型,并且默认为UTF-8,因此我不认为它是有效的UTF-16。主要的问题是字符在CSV中以方括号的形式出现(有时在我的代码中使用不同的路径,通过调整它们以中文符号的形式出现的变量)。我会使用XLSV,但这是一个设置为读取CSV的导入/导出系统,我不确定在调整导入脚本以使用XLSV方面我有多少余地。要测试文件的编码方式,请使用文本编辑器打开它,并指定编辑器应以UTF-16LE打开它。如果角色看起来不错,那就没问题了。要进行更严格的测试,请在十六进制编辑器中打开它,手动检查字节是否符合预期字符的正确编码。至于回旋余地……那么,此导出的目的是什么?如果它被定义为必须导出CSV,那么它的预期编码可能也被定义了?那么您就不必特别担心Excel的兼容性了。如果您确实希望提供一个保证在Excel中正常工作的文件,那么您很难避免专门提供XLSX文件。使用正确的编码将CSV导入Excel是一场噩梦。您可以考虑用PHPOffics/PHPSPEDABLE创建真正的Excel文件吗?
function convertToUTF16LE(&$value, $key) {
    $value = iconv('UTF-8', 'UTF-16LE', $value);
}

$fput = true;
$iconv = true;
$UTF16 = true;
$walk = false;

if($UTF16 == true) {
    header('Content-Encoding: UTF-16LE');
    header('Content-type: text/csv; charset=UTF-16LE');
} else {
    header('Content-Encoding: UTF-8');
    header('Content-Type: text/csv; charset=UTF-8');
}

header('Content-Disposition: attachment; filename="file.csv"');
header("Content-Transfer-Encoding: binary");
header('Accept-Ranges: bytes');
header("Cache-control: private");
header('Pragma: private');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");

$filesize = 0;
$delimiter = '\t';
$prefix = '';

$output = fopen('php://output', 'w');

$headings = array("IATA Code", "Country", "Country Code", "English Name", "Current Name", "Is Primary?", "New Name");
if($UTF16 == true && $walk == true) array_walk($headings, 'convertToUTF16LE');

if($UTF16 == true) $prefix = "\xEF\xBB\xBF"; // chr(255) . chr(254);
$filesize += fwrite($output, $prefix . 'sep=' . $delimiter . PHP_EOL);

if($fput == true) {

    $filesize += fputcsv($output, $headings, $delimiter, '"', "\0");

} else {

    $headings_data = implode($delimiter, $headings);
    $filesize += fwrite($output, $headings_data . PHP_EOL);

}

// This variable exists but the data has not been included in this code.
foreach($data_to_export as $row) {
    foreach($row as $k => $v) {
        if($UTF16 == true) $row[$k] = ($iconv == true ? iconv('UTF-8', 'UTF-16LE', $v) : mb_convert_encoding($v, 'UTF-16LE', 'auto'));
    }

    if($UTF16 == true && $walk == true) array_walk($row, 'convertToUTF16LE');

    if($fput == true) {

        $filesize += fputcsv($output, array(
            $row['code'],
            $row['country'],
            $row['countrycode'],
            $row['english_name'],
            $row['name'],
            ($row['isprimary'] ? 'Y' : 'N'),
            ''
        ), $delimiter, '"', '\0');

    } else {

        $row_data = implode($delimiter, $row);
        $filesize += fwrite($output, $row_data . PHP_EOL);

    }

}

header("Content-Length: ".$filesize);
exit(0);