文字コード判定が上手く行かないケースがあったので、もう少し粘るようなアルゴリズムにした
This commit is contained in:
parent
7259ee3647
commit
45eba30528
@ -28,11 +28,7 @@ class CheckinCsvImporter
|
||||
public function execute()
|
||||
{
|
||||
// Guess charset
|
||||
$head = file_get_contents($this->filename, false, null, 0, 1024);
|
||||
$charset = mb_detect_encoding($head, ['ASCII', 'UTF-8', 'SJIS-win'], true);
|
||||
if (array_search($charset, ['UTF-8', 'SJIS-win'], true) === false) {
|
||||
throw new CsvImportException(['文字コード判定に失敗しました。UTF-8 (BOM無し) または Shift_JIS をお使いください。']);
|
||||
}
|
||||
$charset = $this->guessCharset($this->filename);
|
||||
|
||||
// Open CSV
|
||||
$csv = Reader::createFromPath($this->filename, 'r');
|
||||
@ -101,4 +97,51 @@ class CheckinCsvImporter
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定されたファイルを読み込み、文字コードの判定を行います。
|
||||
* @param string $filename CSVファイル名
|
||||
* @param int $samplingLength ファイルの先頭から何バイトを判定に使用するかを指定
|
||||
* @return string 検出した文字コード (UTF-8, SJIS-win, ...)
|
||||
* @throws CsvImportException ファイルの読み込みに失敗した、文字コードを判定できなかった、または非対応文字コードを検出した場合にスロー
|
||||
*/
|
||||
private function guessCharset(string $filename, int $samplingLength = 1024): string
|
||||
{
|
||||
$fp = fopen($filename, 'rb');
|
||||
if (!$fp) {
|
||||
throw new CsvImportException(['CSVファイルの読み込み中にエラーが発生しました。']);
|
||||
}
|
||||
|
||||
try {
|
||||
$head = fread($fp, $samplingLength);
|
||||
if ($head === false) {
|
||||
throw new CsvImportException(['CSVファイルの読み込み中にエラーが発生しました。']);
|
||||
}
|
||||
|
||||
for ($addition = 0; $addition < 4; $addition++) {
|
||||
$charset = mb_detect_encoding($head, ['ASCII', 'UTF-8', 'SJIS-win'], true);
|
||||
if ($charset) {
|
||||
if (array_search($charset, ['UTF-8', 'SJIS-win'], true) === false) {
|
||||
throw new CsvImportException(['文字コード判定に失敗しました。UTF-8 (BOM無し) または Shift_JIS をお使いください。']);
|
||||
} else {
|
||||
return $charset;
|
||||
}
|
||||
}
|
||||
|
||||
// 1バイト追加で読み込んだら、文字境界に到達して上手く判定できるかもしれない
|
||||
if (feof($fp)) {
|
||||
break;
|
||||
}
|
||||
$next = fread($fp, 1);
|
||||
if ($next === false) {
|
||||
throw new CsvImportException(['CSVファイルの読み込み中にエラーが発生しました。']);
|
||||
}
|
||||
$head .= $next;
|
||||
}
|
||||
|
||||
throw new CsvImportException(['文字コード判定に失敗しました。UTF-8 (BOM無し) または Shift_JIS をお使いください。']);
|
||||
} finally {
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user