2013-02-26 71 views
2

我在PHP脚本中读取文本文件(保存为Unicode UTF16-LE)时遇到了一些麻烦。如何在PHP中读取unicode文本文件?

我的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]);
但仍然没有成功...

+2

“的Unicode” 不是一个编码,可以不保存在文本 “的Unicode”,仅在特定的Unicode编码(包括UTF-8)。 – Quentin 2013-02-26 15:22:58

+0

@Quentin啊OK!我用UTF16-LE保存了它。但是因为我没有在PHP手册(File()函数)中找到编码列表,所以我做了“Unicode”:)我应该在那里放置什么? – Enriqe 2013-02-26 15:24:59

+0

“Thank you”赞成投票: - /我在2天内搜索了Stackoverflow,但因为我不知道UTF8是Unicode的子组,所以我无法搜索正确的关键字。对不起,问....:( – Enriqe 2013-02-26 15:31:36

回答

7

PHP的file功能无法与UTF-16LE编码读取文件。它需要在行结尾字符处分割,但PHP在此仅支持单字节序列,UTF-16LE是一种多字节可变长度编码,与编码到file函数中的行分割过程不兼容。

因此,您正在使用错误的作业功能。那简单就是答案。不是iconv是这里的问题,但只是使用file

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

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

然后从缓冲区中逐行分割(如果缓冲区中的字节用完,请重新从缓冲区重新填充缓冲区),然后您可以使用iconv,如手册页(或您的问题,示例代码你有没有看错,只是照顾你使用正确的参数,所以编码是正确的)。

+0

这只是一个完美的!最后回答,不只是downvotes :)谢谢老兄! – Enriqe 2013-02-27 07:18:07

+0

最后解决我的搜索!试图从数周内完成这件事情尝试了很多事情,但最后你救了我的命!干杯! – M3Dev 2016-06-08 14:53:37

-2

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

function ReadUnicodeFile($fn) 

{

$ FC = “”;

$ fh = fopen($ fn,“rb”)or die(“无法打开要读取的文件:$ fn <br> \ n”);

$ flen = filesize($ fn);

$ bc = fread($ fh,$ flen);

为($ I = 0; $ I < $ FLEN; $ I ++)

{

$c = substr($bc,$i,1); 

if ((ord($c) != 0) && (ord($c) != 13)) 

    $fc = $fc . $c; 

}

如果((ORD(SUBSTR($ FC,0,1 ))== 255)& &(ORD(SUBSTR($ FC,1,1))== 254))

$fc = substr($fc,2); 

返回($ FC);

}

1

下面的代码工作对我来说:

只需使用下面的函数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); 
} 
?> 

From this website