私の側でファイルを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が配列内の値を削除しますか?
追加情報のために置いておきます。助けてくれる人をありがとう!
utf-8に変換する前に、それがどの文字セットかを知る必要があります。それを理解できない場合、それをutf8に変換することはできません。ただし、エンコーディングを決定できない場合、utf-8に変換するめちゃくちゃな方法は、単純にバイトを取り除くことです。 utf-8では有効ではないので、それをフォールバックとして使用できるかもしれません...
警告、テストされていないコード(突然急いでいます)ですが、次のようになります。
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;
}
これを試してみてください。
私が使用した例は、テスト環境で行っていたものであり、コードを少し変更する必要があるかもしれません。
次のデータを含むテキストファイルがありました。
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
配列をより論理的にするために私が書いたものです。
フォームは、サーバーにデータを単純にPOST
sする標準フォームです。
注:$_SERVER["PHP_SELF"]
の使用はセキュリティリスクです 詳細はこちらをご覧ください 。
データが投稿されると、ファイルを変数に格納します。明らかに、multiple
属性を使用している場合、コードはこのようには見えません。
$handle
は、テキストファイルの内容全体を読み取り専用形式で格納します。したがって、"r"
引数です。
$enc
は mb_detect_encoding
関数を使用してエンコーディング(duh)を検出します。
最初は、正しいエンコーディングを取得するのに問題がありました。 encoding_list
をUTF-8のみを使用するように設定し、strict
をtrueに設定します。
エンコーディングがUTF-8の場合は、単に行を出力します。そうでない場合は、 iconv
関数を使用してUTF-8に変換しました。
以下を使用して、ファイルテキストをバイナリデータに変換できます。
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");
これを試してみましょう:
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);
}
function convert_file_to_utf8($source, $target) {
$content=file_get_contents($source);
# detect original encoding
$original_encoding=mb_detect_encoding($content, "UTF-8, ISO-8859-1, ISO-8859-15", true);
# now convert
if ($original_encoding!='UTF-8') {
$content=mb_convert_encoding($content, 'UTF-8', $original_encoding);
}
$bom=chr(239) . chr(187) . chr(191); # use BOM to be on safe side
file_put_contents($target, $bom.$content);
}