某所からDLしたTSVファイルがさあ!
SJISだったりUTF-8だったりUTF-8BOMだったりころっころ文字セット変えてくるのよ! 断りなく!!
ということで、文字セットを判別してUTF-8に変換、UTF-8BOMだったらBOMを取るだけの関数備忘録。
function utf8encode($str, $original_encode_list = array('UTF-8', 'SJIS-win', 'SJIS')){
$original_encode = mb_detect_encoding($str, $original_encode_list);
if($original_encode=='UTF-8'){
// UTF-8 BOM付き
if (preg_match('/^[\x0x\xef][\x0x\xbb][\x0x\xbf]/', $str)) {
// BOM付きからBOM無しへ
$str = substr($str, 3);
}
}else if($original_encode!==false){
$str = mb_convert_encoding($str, 'UTF-8', $original_encode);
}else{
//想定外の文字セットが検出された? 英語ファイルかな? そのまま返せばいいや。
}
return $str;
}
そもそもBOMってなに?
A.Unicode系文字列の先頭数バイトに、「これはUTF-○ですよ」と示すための符号がくっついていること。
バイトオーダーマーク(byte order mark)の略だそう。
ソフトウェアによっては、このBOMが無いと文字セットが判別できないものがある一方、PHP等のウェブ言語では逆にこのBOM符号がよく分からんものとして持て余すらしいです。
で、UTF-8のBOMは「0xEF 0xBB 0xBF」なので、これが感知できた場合は先頭3バイトを取っ払えばOK。
今回はSJISかUTF-8かUTF-8BOMかの選択肢だったのでこうなっていますが、他の文字セットやUTFの可能性がある場合は同様の要件で追記していけば良いです。