function Connection::open

Same name in this branch
  1. 8.9.x core/lib/Drupal/Core/Database/Driver/sqlite/Connection.php \Drupal\Core\Database\Driver\sqlite\Connection::open()
  2. 8.9.x core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php \Drupal\Core\Database\Driver\pgsql\Connection::open()
  3. 8.9.x core/lib/Drupal/Core/Database/Connection.php \Drupal\Core\Database\Connection::open()
Same name in other branches
  1. 9 core/modules/sqlite/src/Driver/Database/sqlite/Connection.php \Drupal\sqlite\Driver\Database\sqlite\Connection::open()
  2. 9 core/modules/mysql/src/Driver/Database/mysql/Connection.php \Drupal\mysql\Driver\Database\mysql\Connection::open()
  3. 9 core/modules/pgsql/src/Driver/Database/pgsql/Connection.php \Drupal\pgsql\Driver\Database\pgsql\Connection::open()
  4. 9 core/lib/Drupal/Core/Database/Connection.php \Drupal\Core\Database\Connection::open()
  5. 10 core/modules/sqlite/src/Driver/Database/sqlite/Connection.php \Drupal\sqlite\Driver\Database\sqlite\Connection::open()
  6. 10 core/modules/mysql/src/Driver/Database/mysql/Connection.php \Drupal\mysql\Driver\Database\mysql\Connection::open()
  7. 10 core/modules/pgsql/src/Driver/Database/pgsql/Connection.php \Drupal\pgsql\Driver\Database\pgsql\Connection::open()
  8. 10 core/lib/Drupal/Core/Database/Connection.php \Drupal\Core\Database\Connection::open()
  9. 11.x core/modules/sqlite/src/Driver/Database/sqlite/Connection.php \Drupal\sqlite\Driver\Database\sqlite\Connection::open()
  10. 11.x core/modules/mysql/src/Driver/Database/mysql/Connection.php \Drupal\mysql\Driver\Database\mysql\Connection::open()
  11. 11.x core/modules/pgsql/src/Driver/Database/pgsql/Connection.php \Drupal\pgsql\Driver\Database\pgsql\Connection::open()
  12. 11.x core/lib/Drupal/Core/Database/Connection.php \Drupal\Core\Database\Connection::open()

Overrides Connection::open

File

core/lib/Drupal/Core/Database/Driver/mysql/Connection.php, line 374

Class

Connection
MySQL implementation of \Drupal\Core\Database\Connection.

Namespace

Drupal\Core\Database\Driver\mysql

Code

public static function open(array &$connection_options = []) {
    if (isset($connection_options['_dsn_utf8_fallback']) && $connection_options['_dsn_utf8_fallback'] === TRUE) {
        // Only used during the installer version check, as a fallback from utf8mb4.
        $charset = 'utf8';
    }
    else {
        $charset = 'utf8mb4';
    }
    // The DSN should use either a socket or a host/port.
    if (isset($connection_options['unix_socket'])) {
        $dsn = 'mysql:unix_socket=' . $connection_options['unix_socket'];
    }
    else {
        // Default to TCP connection on port 3306.
        $dsn = 'mysql:host=' . $connection_options['host'] . ';port=' . (empty($connection_options['port']) ? 3306 : $connection_options['port']);
    }
    // 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=' . $charset;
    if (!empty($connection_options['database'])) {
        $dsn .= ';dbname=' . $connection_options['database'];
    }
    // Allow PDO options to be overridden.
    $connection_options += [
        'pdo' => [],
    ];
    $connection_options['pdo'] += [
        \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
        // So we don't have to mess around with cursors and unbuffered queries by default.
\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => TRUE,
        // Make sure MySQL returns all matched rows on update queries including
        // rows that actually didn't have to be updated because the values didn't
        // change. This matches common behavior among other database systems.
\PDO::MYSQL_ATTR_FOUND_ROWS => TRUE,
        // Because MySQL's prepared statements skip the query cache, because it's dumb.
\PDO::ATTR_EMULATE_PREPARES => TRUE,
        // Limit SQL to a single statement like mysqli.
\PDO::MYSQL_ATTR_MULTI_STATEMENTS => FALSE,
    ];
    try {
        $pdo = new \PDO($dsn, $connection_options['username'], $connection_options['password'], $connection_options['pdo']);
    } catch (\PDOException $e) {
        if ($e->getCode() == static::DATABASE_NOT_FOUND) {
            throw new DatabaseNotFoundException($e->getMessage(), $e->getCode(), $e);
        }
        if ($e->getCode() == static::ACCESS_DENIED) {
            throw new DatabaseAccessDeniedException($e->getMessage(), $e->getCode(), $e);
        }
        throw $e;
    }
    // Force MySQL to use the UTF-8 character set. Also set the collation, if a
    // certain one has been set; otherwise, MySQL defaults to
    // 'utf8mb4_general_ci' (MySQL 5) or 'utf8mb4_0900_ai_ci' (MySQL 8) for
    // utf8mb4.
    if (!empty($connection_options['collation'])) {
        $pdo->exec('SET NAMES ' . $charset . ' COLLATE ' . $connection_options['collation']);
    }
    else {
        $pdo->exec('SET NAMES ' . $charset);
    }
    // Set MySQL init_commands if not already defined.  Default Drupal's MySQL
    // behavior to conform more closely to SQL standards.  This allows Drupal
    // to run almost seamlessly on many different kinds of database systems.
    // These settings force MySQL to behave the same as postgresql, or sqlite
    // in regards to syntax interpretation and invalid data handling.  See
    // https://www.drupal.org/node/344575 for further discussion. Also, as MySQL
    // 5.5 changed the meaning of TRADITIONAL we need to spell out the modes one
    // by one.
    $connection_options += [
        'init_commands' => [],
    ];
    $sql_mode = 'ANSI,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,ONLY_FULL_GROUP_BY';
    // NO_AUTO_CREATE_USER is removed in MySQL 8.0.11
    // https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-11.html#mysqld-8-0-11-deprecation-removal
    $version_server = $pdo->getAttribute(\PDO::ATTR_SERVER_VERSION);
    if (version_compare($version_server, '8.0.11', '<')) {
        $sql_mode .= ',NO_AUTO_CREATE_USER';
    }
    $connection_options['init_commands'] += [
        'sql_mode' => "SET sql_mode = '{$sql_mode}'",
    ];
    // Execute initial commands.
    foreach ($connection_options['init_commands'] as $sql) {
        $pdo->exec($sql);
    }
    return $pdo;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.