Skip to content

Instantly share code, notes, and snippets.

@stefanruijsenaars
Created June 21, 2016 16:46
Show Gist options
  • Save stefanruijsenaars/b7adc20b34206c1c37332c38f9244877 to your computer and use it in GitHub Desktop.
Save stefanruijsenaars/b7adc20b34206c1c37332c38f9244877 to your computer and use it in GitHub Desktop.
diff --git a/includes/database/mysql/database.inc b/includes/database/mysql/database.inc
index a96b053..43fa3d5 100644
--- a/includes/database/mysql/database.inc
+++ b/includes/database/mysql/database.inc
@@ -26,6 +26,8 @@ class DatabaseConnection_mysql extends DatabaseConnection {
// MySQL never supports transactional DDL.
$this->transactionalDDLSupport = FALSE;
+ // Allow the default charset to be overridden in settings.php.
+ $charset = (isset($connection_options['charset']) && $connection_options['charset'] === 'utf8mb4') ? 'utf8mb4' : 'utf8');
$this->connectionOptions = $connection_options;
// The DSN should use either a socket or a host/port.
@@ -39,7 +41,7 @@ class DatabaseConnection_mysql extends DatabaseConnection {
// Character set is added to dsn to ensure PDO uses the proper character
// set when escaping. This has security implications. See
// https://www.drupal.org/node/1201452 for further discussion.
- $dsn .= ';charset=utf8';
+ $dsn .= ';charset=' . $charset;
$dsn .= ';dbname=' . $connection_options['database'];
// Allow PDO options to be overridden.
$connection_options += array(
@@ -63,10 +65,10 @@ class DatabaseConnection_mysql extends DatabaseConnection {
// certain one has been set; otherwise, MySQL defaults to 'utf8_general_ci'
// for UTF-8.
if (!empty($connection_options['collation'])) {
- $this->exec('SET NAMES utf8 COLLATE ' . $connection_options['collation']);
+ $this->exec('SET NAMES ' . $charset . ' COLLATE ' . $connection_options['collation']);
}
else {
- $this->exec('SET NAMES utf8');
+ $this->exec('SET NAMES ' . $charset);
}
// Set MySQL init_commands if not already defined. Default Drupal's MySQL
diff --git a/includes/database/mysql/schema.inc b/includes/database/mysql/schema.inc
index 2a2722e..7796721 100644
--- a/includes/database/mysql/schema.inc
+++ b/includes/database/mysql/schema.inc
@@ -81,7 +81,8 @@ class DatabaseSchema_mysql extends DatabaseSchema {
// Provide defaults if needed.
$table += array(
'mysql_engine' => 'InnoDB',
- 'mysql_character_set' => 'utf8',
+ // Allow the default charset to be overridden in settings.php.
+ 'mysql_character_set' => (isset($info['charset']) && info['charset'] === 'utf8mb4' ? 'utf8mb4' : 'utf8'),
);
$sql = "CREATE TABLE {" . $name . "} (\n";
@@ -109,6 +110,13 @@ class DatabaseSchema_mysql extends DatabaseSchema {
$sql .= ' COLLATE ' . $info['collation'];
}
+ // The row format needs to be either DYNAMIC or COMPRESSED in order to allow
+ // for the innodb_large_prefix setting to take effect, see
+ // https://dev.mysql.com/doc/refman/5.6/en/create-table.html
+ if (isset($info['charset']) && $info['charset'] === 'utf8mb4') {
+ $sql .= ' ROW_FORMAT=DYNAMIC';
+ }
+
// Add table comment.
if (!empty($table['description'])) {
$sql .= ' COMMENT ' . $this->prepareComment($table['description'], self::COMMENT_MAX_TABLE);
diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php
index 7e36a4a..2af2a23 100644
--- a/sites/default/default.settings.php
+++ b/sites/default/default.settings.php
@@ -126,6 +126,30 @@
* );
* @endcode
*
+ * For handling full UTF-8 including multi-byte characters such as emojis, asian
+ * symbols, and mathematical symbols, you may set the collation and charset to
+ * "utf8mb4":
+ * @code
+ * $databases['default']['default']['charset'] = 'utf8mb4';
+ * $databases['default']['default']['collation'] = 'utf8mb4_general_ci';
+ * @endcode
+ * When using this setting on an existing installation, ensure that
+ * all existing tables have been converted to the utf8mb4 charset,
+ * for example by using the utf8mb4_convert contrib module, so as to prevent
+ * mixing data with different charsets.
+ * Note this should only be used when all of the following conditions are met:
+ * - In order to allow for large indexes, MySQL must be set up with the
+ * following my.cnf settings:
+ * [mysqld]
+ * innodb_large_prefix=0
+ * innodb_file_format=barracuda
+ * innodb_file_per_table=true
+ * These settings are available as of MySQL 5.5.14, and are defaults in
+ * MySQL 5.7.7 and up.
+ * - The PHP MySQL driver must support the utf8mb4 charset (libmysqlclient
+ 5.5.3 and up, as well as mysqlnd 5.0.9 and up).
+ * - The MySQL server must support the utf8mb4 charset (5.5.3 and up).
+ *
* You can optionally set prefixes for some or all database table names
* by using the 'prefix' setting. If a prefix is specified, the table
* name will be prepended with its value. Be sure to use valid database
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment