文字コード判定が上手く行かないケースがあったので、もう少し粘るようなアルゴリズムにした
This commit is contained in:
parent
7259ee3647
commit
45eba30528
@ -28,11 +28,7 @@ class CheckinCsvImporter
|
|||||||
public function execute()
|
public function execute()
|
||||||
{
|
{
|
||||||
// Guess charset
|
// Guess charset
|
||||||
$head = file_get_contents($this->filename, false, null, 0, 1024);
|
$charset = $this->guessCharset($this->filename);
|
||||||
$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 をお使いください。']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open CSV
|
// Open CSV
|
||||||
$csv = Reader::createFromPath($this->filename, 'r');
|
$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