web-dev-qa-db-ja.com

インポートされた.csvファイルからBOM()を削除します

インポートしたファイルからBOMを削除したいのですが、機能していないようです。

preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $file);とstr_replaceを試してみました。

私が間違っていることを誰かが見てくれることを願っています。

$filepath = get_bloginfo('template_directory')."/testing.csv";
            setlocale(LC_ALL, 'nl_NL');
            ini_set('auto_detect_line_endings',TRUE);
            $file = fopen($filepath, "r") or die("Error opening file");
            $i = 0;
            while(($line = fgetcsv($file, 1000, ";")) !== FALSE) {
                if($i == 0) {
                    $c = 0;
                    foreach($line as $col) {
                        $cols[$c] = utf8_encode($col);
                        $c++;
                    }
                } else if($i > 0) {
                    $c = 0;
                    foreach($line as $col) {
                        $data[$i][$cols[$c]] = utf8_encode($col);
                        $c++;
                    }
                }
                $i++;
            }

-----------
解決済みバージョン:

setlocale(LC_ALL, 'nl_NL');
ini_set('auto_detect_line_endings',TRUE);
require_once(ABSPATH.'wp-admin/includes/file.php' );

$path = get_home_path();        
$filepath = $path .'wp-content/themes/pon/testing.csv';
$content = file_get_contents($filepath); 
file_put_contents($filepath, str_replace("\xEF\xBB\xBF",'', $content));

// FILE_PUT_CONTENTS AUTOMATICCALY CLOSES THE FILE
$file = fopen($filepath, "r") or die("Error opening file"); 

$i = 0;
while(($line = fgetcsv($file, 1000, ";")) !== FALSE) {
    if($i == 0) {
        $c = 0;
        foreach($line as $col) {
            $cols[$c] = $col;
            $c++;
        }
    } else if($i > 0) {
        $c = 0;
        foreach($line as $col) {
            $data[$i][$cols[$c]] = $col;
            $c++;
        }
    }
    $i++;
}

BOMを削除し、新しいデータで上書きしてファイルを調整することがわかりました。問題は、スクリプトの残りの部分が機能しなくなり、その理由がわからないことです。新しい.csvファイルです

10
Interactive

これを試して:

function removeBomUtf8($s){
  if(substr($s,0,3)==chr(hexdec('EF')).chr(hexdec('BB')).chr(hexdec('BF'))){
       return substr($s,3);
   }else{
       return $s;
   }
}
11
Tomasz

文字エンコード関数が機能せず(状況によっては私の場合のように)、ファイルに常にBOMが含まれていることがわかっている場合は、fseek()を使用して最初の3バイトをスキップできます。 、これはBOMの長さです。

$fp = fopen("testing.csv", "r");
fseek($fp, 3);

また、列に分割した文字が含まれていると、誤った結果が得られるため、explode()を使用してCSV行と列を分割しないでください。代わりにこれを使用してください:

while (!feof($fp)) {
    $arrayLine = fgetcsv($fp, 0, ";", '"');
    ...
}
2
voidmind

file_get_contentsでデータを読み取り、mb_convert_encodingを使用してUTF-8に変換します

更新

$filepath = get_bloginfo('template_directory')."/testing.csv";
$fileContent = file_get_contents($filepath);
$fileContent = mb_convert_encoding($fileContent, "UTF-8");
$lines = explode("\n", $fileContent);
foreach($lines as $line) {
    $conls = explode(";", $line);
    // etc...
}
1
MrRP

@ Tomas'z answer をこれの主なインスピレーションとして使用し、 @ Nolwennigのコメント

// Strip byte order marks from a string
function strip_bom($string, $type = 'utf8') {
    $length = 0;

    switch($type) {
        case 'utf8':
            $length = substr($string, 0, 3) === chr(0xEF) . chr(0xBB) . chr(0xBF) ? 3 : 0;
        break;

        case 'utf16_little_endian':
            $length = substr($string, 0, 2) === chr(0xFF) . chr(0xFE) ? 2 : 0;
        break;
    }

    return $length ? substr($string, $length) : $string;
}
0
Danny Beckett

正しい方法は、ファイルに存在する場合はBOMをスキップすることです( https://www.php.net/manual/en/function.fgetcsv.php#122696 ):

ini_set('auto_detect_line_endings',TRUE);
$file = fopen($filepath, "r") or die("Error opening file");
if (fgets($file, 4) !== "\xef\xbb\xbf") //Skip BOM if present
        rewind($file); //Or rewind pointer to start of file

$i = 0;
while(($line = fgetcsv($file, 1000, ";")) !== FALSE) {
    ...
}
0
AndreyP

スクリプト/アプリ/データベースが必要とするものに入力を再エンコードする方法の手がかりを与えるBOMはありませんか?削除するだけでは役に立ちません。

これは、文字列(file_get_contents()を使用してファイルから取得)をUTF-8でエンコードし、BOMも削除する方法です。

switch (true) { 
    case (substr($string,0,3) == "\xef\xbb\xbf") :
        $string = substr($string, 3);
        break;
    case (substr($string,0,2) == "\xfe\xff") :                            
        $string = mb_convert_encoding(substr($string, 2), "UTF-8", "UTF-16BE");
        break;
    case (substr($string,0,2) == "\xff\xfe") :                            
        $string = mb_convert_encoding(substr($string, 2), "UTF-8", "UTF-16LE");
        break;
    case (substr($string,0,4) == "\x00\x00\xfe\xff") :
        $string = mb_convert_encoding(substr($string, 4), "UTF-8", "UTF-32BE");
        break;
    case (substr($string,0,4) == "\xff\xfe\x00\x00") :
        $string = mb_convert_encoding(substr($string, 4), "UTF-8", "UTF-32LE");
        break;
    default:
        $string = iconv(mb_detect_encoding($string, mb_detect_order(), true), "UTF-8", $string);
};
0
Lisa