Как оставить в 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% решение, но оно хоть дает не потерять строку из прайса и она пишется в базу.

→ Ссылка
Автор решения: Total Pusher

Смените локаль на нужную вам, затем верните ту, что была. Возвращать нужно чтобы не сломать в другом месте. Вот типичный вариант использования:

$currentLocale = setlocale(LC_CTYPE, '0');
setlocale(LC_CTYPE, 'ru_RU.utf8');

/** Тут выполняете что вам нужно */

setlocale(LC_CTYPE, $currentLocale);
→ Ссылка