MySQL обрезает текст на сложном символе-картинке

RussCoder

Столкнулся со следующей проблемой. Имеем текст

<p><strong><span style="font-size: medium;">
Текст Текст Текст Текст
</span></strong></p>

При вставке в базу MySQL текст обрезается по символ ?, то есть остается

<p><strong><span style="font-size: medium;">
Текст Текст Текст Текст </span></strong></p>

Вставка происходит в коде php:

$text = PHP_slashes($text); // экранируем кавычки
$sql = "INSERT INTO `{$this->table}` (`text`) VALUE ('$text')";
$this->db->execute($sql);

Попробовал вставить вручную в базу это сообщение - все сработало, только ? заменился на ?. Такое поведение вполне устраивает, можно бы и вовсе удалить такие символы из сообщения.

Аналогичная проблема на символах ? ? ? и т.д. Можно ли как-то поправить настройки базы или что-то сделать в коде php, чтобы такие символы переводились в ? или удалялись ?

P.S.: Больше интересует не конкретное решение замены символов в строке, а настройки на все случаи - чтобы база не резала текст, а как-то его сохраняла, заменяя непонятные ей символы.

Update: строка запроса

INSERT INTO `mails` (`text`) VALUE ('<p><strong><span style="\"font-size:" medium;\"="">Текст Текст Текст Текст </span></strong></p><strong>')
</strong>

Только вместо ? в текстовом файле отображается квадратик с вопросом

3 ответа

RussCoder

Ваша база сейчас работает в кодировке utf-8 в которой на 1 символ максимум выделяется 3 байта. Из-за этого ваши фигурные символы (а так же символы китайского и японского языков) не могут быть записаны в базу, так как имеют размер 4 байта.

Следует перевести базу данных на работу в кодировке utf-8 с поддержкой символов размером до 4 байт.

  1. Если MySQL имеет версию ниже 5.5.3, его следует обновить.
  2. Сделать полный бекап базы данных.
  3. Для перевода базы на 4-x байтный utf-8 нужно выполнить команду

    ALTER DATABASE название_базы CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci;
  4. Для каждой таблицы базы нужно выполнить команду такого вида

    ALTER TABLE название_таблицы CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
  5. Для каждого поля содержащего текстовую информацию в каждой таблице нужно выполнить команду (примерный вид, зависит от структуры поля)

    ALTER TABLE название_таблицы CHANGE название_столбца название_столбца VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

    Пункты 3-5 можно выполнить например через phpmyadmin.

  6. В код php нужно добавить сразу после коннекта к базе выполнение запроса вида

    SET NAMES 'utf8mb4' COLLATE 'utf8mb4_general_ci'

P.S. Про установку кодировки соединения https://ru.stackoverflow.com/a/726863/186083


RussCoder

Насколько я понимаю Вам вместо знака ? и других подобных необходимо использовать его код в html, если html код приходит извне то парсить регуляркой так же по коду...


RussCoder

Нашел решение. Не совсем то, что хотелось, но пока что работает, хотя я буду ждать более нормальные варианты.

function clearText($text) { $text = iconv('utf-8', 'windows-1251//IGNORE', $text); $text = iconv('windows-1251', 'utf-8//IGNORE', $text); return $text;
}

Эта функция убирает все "фигурные" символы из текста.

Решение типа

$text = iconv('utf-8', 'utf-8//IGNORE', $text);

не работает.

licensed under cc by-sa 3.0 with attribution.