5

我在我的 PHP 脚本中读取文本文件(以 Unicode UTF16-LE 保存)时遇到了一些问题。

我的 PHP 脚本(出于某些原因)以 UTF-8 格式保存。

这是我的代码:

$lines = file("./somedir/$filename");

for ($i=0; $i < count($lines); $i++) {
    $lines[$i] = iconv("Unicode", "UTF-8", $lines[$i]); // converting to UTF8
}

echo "[0]:".$lines[0]; // outputs CORRECT text (like "This is the first line")
echo "[1]:".$lines[1]; // outputs something like çæ¤ææ¬çææ¸ææ°ã

请问有什么想法吗?我检查了值,count($lines)它完全正确......谢谢。

编辑:
好的,所以我尝试了iconv("UTF-16", "UTF-8", $lines[$i]);
我也尝试了iconv("UTF-16LE", "UTF-8", $lines[$i]);
但仍然没有成功...

4

3 回答 3

13

PHP 的file函数无法读取 UTF-16LE 编码的文件。它需要在行结束符处进行拆分,但 PHP 在这里只支持单字节序列,UTF-16LE 是一种多字节变长编码,与编码到file函数中的行拆分过程不兼容。

因此,您在工作中使用了错误的功能。答案就是这么简单。不是iconv这里的问题,而只是使用file.

相反,您需要将文件读入缓冲区,一行接一行地从缓冲区中取出,然后重新编码为 UTF-8。

首先要了解该文件中使用的行分隔符。由于 PHP 的文件函数(和字符串函数以及字符串本身)是基于二进制的,因此采用字符串形式的二进制序列和strpos定位它的函数。

然后从缓冲区中逐行拆分(如果字节用完,请再次从文件中重新填充缓冲区),然后您可以iconv按照手册页中的说明使用(或者您的问题,您没有查看的示例代码错了,请注意使用正确的参数,以便编码正确)。

于 2013-02-26T22:42:14.150 回答
6

以下代码适用于我:

只需使用以下函数 fopen_utf8 而不是 fopen。

<?php
# http://www.practicalweb.co.uk/blog/2008/05/18/reading-a-unicode-excel-file-in-php/
function fopen_utf8($filename){
    $encoding='';
    $handle = fopen($filename, 'r');
    $bom = fread($handle, 2);
//  fclose($handle);
    rewind($handle);

    if($bom === chr(0xff).chr(0xfe)  || $bom === chr(0xfe).chr(0xff)){
            // UTF16 Byte Order Mark present
            $encoding = 'UTF-16';
    } else {
        $file_sample = fread($handle, 1000) + 'e'; //read first 1000 bytes
        // + e is a workaround for mb_string bug
        rewind($handle);

        $encoding = mb_detect_encoding($file_sample , 'UTF-8, UTF-7, ASCII, EUC-JP,SJIS, eucJP-win, SJIS-win, JIS, ISO-2022-JP');
    }
    if ($encoding){
        stream_filter_append($handle, 'convert.iconv.'.$encoding.'/UTF-8');
    }
    return  ($handle);
} 
?>

从这个网站

于 2017-08-22T00:22:20.403 回答
-2

这是我用来将 Unicode 转换为普通文本格式的代码。

function ReadUnicodeFile($fn)    
  $fc = "";    
  $fh = fopen($fn,"rb") or die("Cannot open file for read: $fn&lt;br&gt;\n");    
  $flen = filesize($fn);    
  $bc = fread($fh, $flen);

  for ($i=0; $i&lt;$flen; $i++){    
    $c = substr($bc,$i,1);    
    if ((ord($c) != 0) && (ord($c) != 13))    
      $fc = $fc . $c;    
  }

  if ((ord(substr($fc,0,1)) == 255) && (ord(substr($fc,1,1)) == 254))    
    $fc = substr($fc,2);    
  return ($fc);    
}
于 2014-07-21T08:39:14.693 回答