用fgets读取csv文件的PHP字符编码
我有一个网站,每月通过FTP接收一次CSV文件。多年来,它一直是一个ASCII文件。现在我一个月收到UTF-8,下一个月收到UTF-16,下一个月收到UTF-16。也许下个月我会得到UTF-32。Fgets返回UTF文件开头的字节顺序标记。如何让PHP自动识别字符编码?我尝试了mb_detect_编码,无论文件类型如何,它都返回ASCII。我更改了代码以读取BOM表,并显式地将字符编码转换为mb_convert_编码。直到最新的文件,即UTF-16LE,这种方法一直有效。在此文件中,它正确读取第一行,所有后续行显示为问号(“?”)。我做错了什么用fgets读取csv文件的PHP字符编码,php,encoding,fgets,Php,Encoding,Fgets,我有一个网站,每月通过FTP接收一次CSV文件。多年来,它一直是一个ASCII文件。现在我一个月收到UTF-8,下一个月收到UTF-16,下一个月收到UTF-16。也许下个月我会得到UTF-32。Fgets返回UTF文件开头的字节顺序标记。如何让PHP自动识别字符编码?我尝试了mb_detect_编码,无论文件类型如何,它都返回ASCII。我更改了代码以读取BOM表,并显式地将字符编码转换为mb_convert_编码。直到最新的文件,即UTF-16LE,这种方法一直有效。在此文件中,它正确读取第
$fhandle = fopen( $file_in, "r" );
if ( fhandle === false )
{
echo "<p class=redbold>Error opening file $file_in.</p>";
die();
}
$i = 0;
while( ( $line = fgets( $fhandle ) ) !== false )
{
$i++;
// Detect encoding on first line. Actual text always begins with string "Document"
if ( $i == 1 )
{
$line_start = substr( $line, 0, 4 );
$line_start_hex = bin2hex( $line_start );
$utf16_start = 'fffe4400';
$utf8_start = 'efbbbf44';
if ( strcmp( $line_start, 'Docu' ) == 0 )
{ $char_encoding = 'ASCII'; }
elseif ( strcmp( $line_start_hex, 'efbbbf44' ) == 0 )
{
$char_encoding = 'UTF-8';
$line = substr( $line, 3 );
}
elseif ( strcmp( $line_start_hex, 'fffe4400' ) == 0 )
{
$char_encoding = 'UTF-16LE';
$line = substr( $line, 2 );
}
elseif ( strcmp( $line_start_hex, 'feff4400' ) == 0 )
{
$char_encoding = 'UTF-16BE';
$line = substr( $line, 2 );
}
else
{
echo "<p class=redbold>Error, unknown character encoding. Line =<br>", $line_start_hex, '</p>';
require( '../footer.php' );
die();
}
echo "<p>char_encoding = $char_encoding</p>";
}
// Convert UTF
if ( $char_encoding != 'ASCII' )
{
$line = mb_convert_encoding( $line, 'ASCII', $char_encoding);
}
echo '<p>'; var_dump( $line ); echo '</p>';
}
我的建议是将所有内容转换为UTF-8或ASCII(如果您试图将所有内容转换为UTF-8或ASCII,则从您发布的代码中不太确定) 或者
您可以利用
mb\u detect\u编码
来完成繁重的工作显式地传递要检测的顺序和可能的编码,并使用严格的参数。阿尔索
请使用file\u get\u contents
,如果文件是UTF-16LE格式,fgets
会帮您搞糟
<?php
header( "Content-Type: text/html; charset=utf-8");
$input = file_get_contents( $file_in );
$encoding = mb_detect_encoding( $input, array(
"UTF-8",
"UTF-32",
"UTF-32BE",
"UTF-32LE",
"UTF-16",
"UTF-16BE",
"UTF-16LE"
), TRUE );
if( $encoding !== "UTF-8" ) {
$input = mb_convert_encoding( $input, "UTF-8", $encoding );
}
echo "<p>$encoding</p>";
foreach( explode( PHP_EOL, $input ) as $line ) {
var_dump( $line );
}
不幸的是,对于某些UTF文件,mb\u detect\u编码似乎返回“ASCII”。哎呀,错过了问题的这一部分。。回到绘图板,但是ascii是unicode的一个子集(前255个小数点),因此它们应该很容易转换。只需转换为ascii,不要使用多字节字符串。哦,你想过对提供FTP数据的人大喊大叫吗?我试过对提供文件的人大喊大叫,但对县政府机构大喊大叫就像对砖墙说话一样。他们做什么就做什么!“just convert to ASCII”是指我现在使用的mb_convert_encoding()的其他技术吗?
$utf8Line = iconv( mb_detect_encoding( $line ), 'UTF-8', $line );
$asciiLine = iconv( mb_detect_encoding( $line ), 'ASCII', $line );
<?php
header( "Content-Type: text/html; charset=utf-8");
$input = file_get_contents( $file_in );
$encoding = mb_detect_encoding( $input, array(
"UTF-8",
"UTF-32",
"UTF-32BE",
"UTF-32LE",
"UTF-16",
"UTF-16BE",
"UTF-16LE"
), TRUE );
if( $encoding !== "UTF-8" ) {
$input = mb_convert_encoding( $input, "UTF-8", $encoding );
}
echo "<p>$encoding</p>";
foreach( explode( PHP_EOL, $input ) as $line ) {
var_dump( $line );
}