2017-10-20 38 views
7

是否可以將文件轉換爲UTF-8?如何在PHP中將文件轉換爲UTF-8?

如果我有提交後對文件的訪問

$_FILES['file']['tmp_name'] 

注:用戶可以上傳CSV文件與任何類型的字符集,我通常會遇到未知的8位字符集。

我嘗試

$row = array(); 
$datas = file($_FILES['file']['tmp_name']); 
foreach($datas as $data) { 
    $data = mb_convert_encoding($data, 'UTF-8'); 
    $row[] = explode(',', $data); 
} 

但問題是,這個代碼刪除,如單引號的特殊字符。

我的第一個問題是htmlspecialchars remove the value inside the array?

我把它的其他信息。感謝那些可以幫助的人!

+0

可以試試的任何示例文件? –

+4

你可能會在這裏找到你的答案:https://stackoverflow.com/a/7980354/1348344 –

+0

所以最好的解決方案是檢測它是否包含utf-8? –

回答

2

試試看。
我用過的例子是我在測試環境中做的事,你可能需要稍微改變一下代碼。

我與在下列數據的文本文件:

test 
café 
áÁÁÁááá 
žžœš¥± 
ÆÆÖÖÖasØØ 
ß 

然後,我有歷時文件輸入並進行以下的代碼的形式:

function neatify_files(&$files) { 
    $tmp = array(); 
    for ($i = 0; $i < count($_FILES); $i++) { 
     for ($j = 0; $j < count($_FILES[array_keys($_FILES)[$i]]["name"]); $j++) { 
      $tmp[array_keys($_FILES)[$i]][$j]["name"] = $_FILES[array_keys($_FILES)[$i]]["name"][$j]; 
      $tmp[array_keys($_FILES)[$i]][$j]["type"] = $_FILES[array_keys($_FILES)[$i]]["type"][$j]; 
      $tmp[array_keys($_FILES)[$i]][$j]["tmp_name"] = $_FILES[array_keys($_FILES)[$i]]["tmp_name"][$j]; 
      $tmp[array_keys($_FILES)[$i]][$j]["error"] = $_FILES[array_keys($_FILES)[$i]]["error"][$j]; 
      $tmp[array_keys($_FILES)[$i]][$j]["size"] = $_FILES[array_keys($_FILES)[$i]]["size"][$j]; 
     } 
    } 
    return $files = $tmp; 
} 

if (isset($_POST["submit"])) { 
    neatify_files($_FILES); 
    $file = $_FILES["file"][0]; 

    $handle = fopen($file["tmp_name"], "r"); 
    while ($line = fgets($handle)) { 
     $enc = mb_detect_encoding($line, "UTF-8", true); 
     if (strtolower($enc) != "utf-8") { 
      echo "<p>" . (iconv($enc, "UTF-8", $line)) . "</p>"; 
     } else { 
      echo "<p>$line</p>"; 
     } 
    } 
} 
?> 
<form action="<?= $_SERVER["PHP_SELF"]; ?>" method="POST" enctype="multipart/form-data"> 
    <input type="file" name="file[]" /> 
    <input type="submit" name="submit" value="Submit" /> 
</form> 

功能neatify_files是我寫的東西使$_FILES陣列的佈局更合理。

該表格是一種標準格式,只需將數據發送到服務器即可。
注意:使用$_SERVER["PHP_SELF"]存在安全風險,see here for more

當數據發佈時,我將文件存儲在一個變量中。顯然,如果你使用multiple屬性,你的代碼看起來不會像這樣。

$handle以只讀格式存儲文本文件的全部內容;因此有"r"的說法。使用mb_detect_encoding函數來檢測編碼(duh)。
起初我在獲得正確的編碼方面遇到了問題。將encoding_list設置爲僅使用UTF-8,並將strict設置爲true。

如果編碼是UTF-8,那麼我只需打印該行,如果它沒有使用iconv函數將其轉換爲UTF-8。

1

您可以將文件文本轉換成二進制數據通過以下

FUNCTION bin2text($bin_str) 
{ 
    $text_str = ''; 
    $chars = EXPLODE("\n", CHUNK_SPLIT(STR_REPLACE("\n", '', $bin_str), 8)); 
    $_I = COUNT($chars); 
    FOR($i = 0; $i < $_I; $text_str .= CHR(BINDEC($chars[$i])), $i ); 
    RETURN $text_str; 
} 

FUNCTION text2bin($txt_str) 
{ 
    $len = STRLEN($txt_str); 
    $bin = ''; 
    FOR($i = 0; $i < $len; $i ) 
    { 
     $bin .= STRLEN(DECBIN(ORD($txt_str[$i]))) < 8 ? STR_PAD(DECBIN(ORD($txt_str[$i])), 8, 0, STR_PAD_LEFT) : DECBIN(ORD($txt_str[$i])); 
    } 
    RETURN $bin; 
} 

將數據轉換成二進制後,您只需將文本更改爲PHP方法mb_convert_encoding($ FILETEXT,「UTF-8」) ;

+1

爲什麼要大寫PHP關鍵字? – zessx

+0

不是問題,但這有點奇怪。這是否意味着你從不使用編輯器的自動完成和片段? – zessx

2

在將其轉換爲utf-8之前,您需要知道它是什麼字符集。 如果你無法弄清楚,你不能以任何理智的方式將其轉換爲utf8 ..然而,如果編碼無法確定,將其轉換爲utf-8的一種瘋狂方法是,將 簡單地剝離這不正好是UTF-8格式的任何有效字節,你 也許能夠使用它作爲後備...

警告,未經測試的代碼(有急事突然IM),但看起來像這樣的:

foreach ($datas as $data) { 
    $encoding = guess_encoding ($data); 
    if (empty ($encoding)) { 
     // encoding cannot be determined... 
     // as a fallback, we simply strip any bytes that isnt valid utf-8... 
     // obviously this isn't a reliable conversion scheme. 
     // also this could probably be improved 
     $data = iconv ("ASCII", "UTF-8//TRANSLIT//IGNORE", $text); 
    } else { 
     $data = mb_convert_encoding ($data, 'UTF-8', $encoding); 
    } 
    $row [] = explode (',', $data); 
} 
function guess_encoding(string $str): string { 
    $blacklist = array (
      'pass', 
      'auto', 
      'wchar', 
      'byte2be', 
      'byte2le', 
      'byte4be', 
      'byte4le', 
      'BASE64', 
      'UUENCODE', 
      'HTML-ENTITIES', 
      '7bit', 
      '8bit' 
    ); 
    $encodings = array_flip (mb_list_encodings()); 
    foreach ($blacklist as $tmp) { 
     unset ($encodings [$tmp]); 
    } 
    $encodings = array_keys ($encodings); 
    $detected = mb_detect_encoding ($str, $encodings, true); 
    return (string) $detected; 
} 
1

讓我們試試這個:

function encode_utf8($data) 
{ 
    if ($data === null || $data === '') { 
     return $data; 
    } 
    if (!mb_check_encoding($data, 'UTF-8')) { 
     return mb_convert_encoding($data, 'UTF-8'); 
    } else { 
     return $data; 
    } 
} 

用法:

$content = file_get_contents($_FILES['file']['tmp_name']); 
$content = encode_utf8($content); 

$rows = explode("\n", $content); 
foreach ($rows as $row) { 
    print_r($row); 
}