Как оставить в UTF-8 строке только 2х байтовые символы?
Есть обработчик CSV файлов, с последующей фильтрацией нужных данных по эталонным строкам и дальнейшей записью в MySQL.
Проблема заключается в том что не всегда данные прилетают чистыми и непонятно что искать и удалять для фильтрации.
На данный момент нами применяется такая функция, но она все же пропускает мусор, и база данных при импорте падает с ошибкой 22007, даже с учетом того что кодировка в таблице и соединение utf8mb4
public function normalizeString($string): string
{
return trim(mb_strtolower(
preg_replace('/[^a-zA-Zа-яА-Я0-9 -\/+]/ui', '', $string)
));
}
Прикрепляю лог файл в котором проявляется эта ошибка в системе, где видно что это ошибка не связана со смещением столбцов в CVS и не связана с датой.
Исходный файл CSV
Ответы (2 шт):
В итоге помогло решение из, функция Encoding::toUTF8 из библиотеки
В предварительной таблице, если включить HEX режим, видно что в конце строки есть битый непечатаемый и неопределяемый байт (на скрине ниже это видно).
public function storeSingleChunk($attributes, $rows)
{
foreach ($rows as $row){
try {
$this->execute($attributes, $row);
} catch (Exception $e) {
$row[4] = Encoding::toUTF8($row[4]);
$this->execute($attributes, $row);
\Yii::error($e->getMessage(), 'error');
}
}
}
На входе строка СТАБИЛИЗАТОРА СТОЙКА ПЕ�
На выходе строка СТАБИЛИЗАТОРА СТОЙКА ПЕÐ
Да это не 100% решение, но оно хоть дает не потерять строку из прайса и она пишется в базу.
Смените локаль на нужную вам, затем верните ту, что была. Возвращать нужно чтобы не сломать в другом месте. Вот типичный вариант использования:
$currentLocale = setlocale(LC_CTYPE, '0');
setlocale(LC_CTYPE, 'ru_RU.utf8');
/** Тут выполняете что вам нужно */
setlocale(LC_CTYPE, $currentLocale);
