编写时编码有问题

时间:2015-06-30 10:14:40

标签: php utf-8 fwrite

我正在尝试用这段代码将一些(生成的)数据写入文件:

define("LANG_DIR", "/var/www/html/app/lang/");
define("TAB", "\t");
define("NL", "\n");
define('FILE_START', '<?php' . NL . NL . "return array(" . NL);
define('FILE_END', NL . ');');

// Some parsing here    

foreach ($fileContent as $fileName => $value) {
    $fileString = FILE_START;

    foreach ($value as $arrayKey => $arrayValue) {
        $fileString .= TAB . "'" . $arrayKey . "'" . TAB . TAB . "=>" . TAB . TAB .  "'" . $arrayValue . "'," . NL;
    }

    $fileString .= FILE_END;

    $filePath = LANG_DIR . $desLang . "/" . $fileName . ".php";
    $filePath = strval(str_replace("\0", "", $filePath));

    $handle = fopen($filePath, "w+b");
    fwrite($handle, $fileString); // "\xEF\xBB\xBF" .
    fclose($handle);

    echo $filePath . "<br />";
    echo '<br /><textarea rows="10" cols="100"> ' . $fileString . '</textarea><br />';
}

这将导致文件看起来像这样:

3c3f 7068 700a 0a72 6574 7572 6e20 6172
7261 7928 0a09 2700 6900 6e00 6100 6300
7400 6900 7600 6500 2709 093d 3e09 0927
0049 006e 0061 006b 0074 0069 0076 0065
0020 0047 0061 0062 0065 006c 0073 0074
0061 0070 006c 0065 0072 0027 2c0a 0927
006e 0069 0065 0075 0077 0027 0909 3d3e
0909 2700 4e00 6500 7500 6500 7200 2000
4700 6100 6200 6500 6c00 7300 7400 6100
7000 6c00 6500 7200 272c 0a09 2700 6900
6400 2709 093d 3e09 0927 0049 0044 0027
2c0a 0927 006e 0061 006d 0065 0027 0909
3d3e 0909 2700 4e00 6100 6d00 6500 2000
4700 6100 6200 6500 6c00 7300 7400 6100
7000 6c00 6500 7200 272c 0a09 2700 7300
7400 6100 7400 7500 7300 2709 093d 3e09
0927 0053 0074 0061 0074 0075 0073 0027
2c0a 0927 0069 0070 0027 0909 3d3e 0909
2700 4900 5000 2000 4e00 7500 6d00 6d00
6500 7200 272c 0a09 2700 6100 6300 7400
6900 6f00 6e00 2709 093d 3e09 0927 0041
006b 0074 0069 006f 006e 0065 006e 0027
2c0a 0927 0061 0063 0074 0069 0076 0065
0027 0909 3d3e 0909 2700 4100 6b00 7400
6900 7600 272c 0a09 2700 6200 7500 7400
7400 6f00 6e00 5f00 7400 6900 7400 6c00
6500 5f00 6e00 6500 7700 2709 093d 3e09
0927 0045 0069 006e 0065 006e 0020 006e
0065 0075 0065 006e 0020 0047 0061 0062
0065 006c 0073 0074 0061 0070 006c 0065
0072 0020 0068 0069 006e 007a 0075 0066
00fc 0067 0065 006e 0027 2c0a 0927 0062
0075 0074 0074 006f 006e 005f 0074 0069
0074 006c 0065 005f 0065 0064 0069 0074
0027 0909 3d3e 0909 2700 4400 6900 6500
7300 6500 6e00 2000 4700 6100 6200 6500
6c00 7300 7400 6100 7000 6c00 6500 7200
2000 6200 6500 6100 7200 6200 6500 6900
7400 6500 6e00 272c 0a0a 293b 

如果我使用所谓的UTF-8 BOM:

fwrite($handle, "\xEF\xBB\xBF" . $fileString);

我将此写入文件:

enter image description here

但当我将它回显到textarea时,我得到以下输出:

return array(
    'inactive'      =>      'Inaktive Gabelstapler',
    'nieuw'     =>      'Neuer Gabelstapler',
    'id'        =>      'ID',
    'name'      =>      'Name Gabelstapler',
    'status'        =>      'Status',
    'ip'        =>      'IP Nummer',
    'action'        =>      'Aktionen',
    'active'        =>      'Aktiv',
    'button_title_new'      =>      'Einen neuen Gabelstapler hinzufügen',
    'button_title_edit'     =>      'Diesen Gabelstapler bearbeiten',

);

所以我的问题非常简单......发生了什么?我听说有人说过utf-8和ISO的东西,但我对此一无所知......

修改 正如@axiac评论的那样,我现在以这种方式编写了定义:

$fileString = convertEnc(FILE_START);

foreach ($value as $arrayKey => $arrayValue) {
    $fileString .= convertEnc(TAB) . "'" . $arrayKey . "'" . convertEnc(TAB) . convertEnc(TAB) . "=>" . convertEnc(TAB) . convertEnc(TAB) .  "'" . $arrayValue . "'," . convertEnc(NL);
}

$fileString .= convertEnc(FILE_END);

//更多代码...

function convertEnc($input){
    return mb_convert_encoding($input, 'UTF-16');
}

这将导致:

enter image description here

哪个更好(你现在可以阅读一些文字),但仍然不是我所期待的......

1 个答案:

答案 0 :(得分:1)

正如问题的评论(以及聊天内容)中所述,我认为$fileContent中的数据编码错误;它似乎是UTF-16,而UTF-8更有用,也更容易操作。

我建议您尝试修复源$fileContent的数据编码(生成文件时)。

如果无法做到这一点,我就会编写代码:

// Create the converting function
// It assumes the input string is encoded as UTF-16
// and converts the encoding to UTF-8
$fnFixEncoding = function ($input) {
    return mb_convert_encoding($input, 'UTF-8', 'UTF-16');
};

// Process all the files
foreach ($fileContent as $fileName => $value) {
    // Fix the encoding of the keys and values of $value individually
    // then re-compose the array
    $value = array_combine(
        array_map($fnFixEncoding, array_keys($value)),
        array_map($fnFixEncoding, array_values($value))
    );

    // Generate the PHP code
    $text = '<?php return '.var_export($value, TRUE).';';

    // Generate the file path
    $filePath = LANG_DIR.$desLang.'/'.$fileName.'.php';
    // If $fileName is also encoded as UTF-16 you need to change its encoding too
    // Use $fnFixEncoding($fileName) instead of $fileName in the line above

    // Write the code in the file
    file_put_contents($filePath, $text);
}

// That's all!

说明

如果输入字符串的编码未知或者总是相同,则编码函数必须具有更精细的实现,可以使用mb_detect_encoding()来查找输入字符串的编码并将其作为第三个传递mb_convert_encoding()的参数:

$fnFixEncoding = function ($input) {
    // The third argument is a list of possible encodings used by $input
    $enc = mb_detect_encoding($input, ['UTF-16', 'UTF-8', 'ISO8859-1']);
    return mb_convert_encoding($input, 'UTF-8', $enc);
};