После установки Drupal версии 7, на странице статуса можно встретить надпись
image

Database 4 byte UTF-8 support
Enabled, but database tables need conversion
Please convert all database tables to utf8mb4 prior to enabling it in settings.php. See the documentation on adding 4 byte UTF-8 support for more information.

Здесь, как известно, речь идёт о том, что неплохо было бы вам сменить кодировку своей базы таким образом, чтобы она могла корректно сохранять эмоджи, китайские иероглифы, математические и другие спец. символы.

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

  1. Удостовериться, что в конфигах Mysql есть записи

    [mysqld]
    innodb_large_prefix=true
    innodb_file_format=barracuda
    innodb_file_per_table=true
    
  2. Убедиться, что ваш MySQL драйвер поддерживает кодировку utf8mb4 (libmysqlclient 5.5.3 и выше, также как mysqlnd 5.0.9 и выше)

  3. Проверить, что MySQL сервер поддерживает кодировку utf8mb4 (5.5.3 и выше).

Если всё в порядке, тогда можно подготовить сайт. Для этого нужно в вашем settings.php, в массиве настроек коннекции к базе, добавить ключи collation  и charset. Результат должен выглядеть примерно так:

<?php
$databases['default']['default'] = array(
  'driver' => 'mysql',
  'database' => 'databasename',
  'username' => 'username',
  'password' => 'password',
  'host' => 'localhost',
  'charset' => 'utf8mb4',
  'collation' => 'utf8mb4_general_ci',
);

Уже после завершения этого этапа на странице статуса сайта можно увидеть примерно следующую картину:
drupal-db-collation

На этом прелюдия заканчивается и для активной фазы изменения кодировки базы и таблиц начинаются переводы стрелок:

  1. У нас есть возможность нажать на каждую из ссылок на скриншоте выше, по которой можно будет подтвердить свои намерения о изменении кодировки, кликнув специальную кнопку... 
  2. Нам говорят, поставьте модуль, который добавит drush команду, которая позволит изменить кодировку.
  3. Нашлись добрые люди, которые написали модуль и обернули это дело в функцию. Но сам модуль тоже ничего не делает.

Мне всё это не нравится, т.к. реально вся эта тема укладывается в 4 строчки.

db_query("ALTER DATABASE my_db CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci");
foreach (db_query('show tables')->fetchCol() as $table) {
  db_query("ALTER TABLE $table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci");
}

Но конечно же, я добавил вкусности и няшности, для удобства и безопасности выполнения процедуры. Создаём свой hook_update_N и запускаем

<?php
/**
 * Implements hook_update_n().
 */
function MYMODULE_update_N() {
  $connection = Database::getConnection();
  $database_info = $connection->getConnectionOptions();
  $database = @$database_info['database'] ?: NULL;
  $collation = @$database_info['collation'] ?: NULL;
  $charset = @$database_info['charset'] ?: NULL;

  if (!$collation) {
    throw new Exception('Collation is not configured');
  }
  if (!$charset) {
    throw new Exception('Charset is not configured');
  }
  if ($database && $collation && $charset) {
    db_query("ALTER DATABASE $database CHARACTER SET = $charset COLLATE = $collation");
    foreach (db_query('show tables')->fetchCol() as $table) {
      db_query("ALTER TABLE $table CONVERT TO CHARACTER SET $charset COLLATE $collation");
    }

    // Эта проверка необходима, для того, чтобы убрать сообщение
    // о некоректной кодировке со страницы статуса т.к. Drupal
    // делает такую проверку единажды, при установке сайта.
    if ($connection->utf8mb4IsConfigurable() && $connection->utf8mb4IsActive()) {
      variable_set('drupal_all_databases_are_utf8mb4', TRUE);
    }
  }
}

image

Убедитесь, что на данный момент у вас есть в переменной $databases, находящейся в settings.php записи о charset и collation, о чем написано выше.

P.S.
Если будут отзывы о необходимости создания модуля, который делает это не выходя за рамки UI, накидаю такой в следующий раз.

Другие посты