diff --git a/libraries/joomla/database/driver/mysql.php b/libraries/joomla/database/driver/mysql.php index 2328cd434c3ee..9a0aee2f53e0a 100644 --- a/libraries/joomla/database/driver/mysql.php +++ b/libraries/joomla/database/driver/mysql.php @@ -512,16 +512,24 @@ private function hasProfiling() private function serverClaimsUtf8mb4Support() { $client_version = mysql_get_client_info(); + $server_version = $this->getVersion(); - if (strpos($client_version, 'mysqlnd') !== false) + if (version_compare($server_version, '5.5.3', '<')) { - $client_version = preg_replace('/^\D+([\d.]+).*/', '$1', $client_version); - - return version_compare($client_version, '5.0.9', '>='); + return false; } else { - return version_compare($client_version, '5.5.3', '>='); + if (strpos($client_version, 'mysqlnd') !== false) + { + $client_version = preg_replace('/^\D+([\d.]+).*/', '$1', $client_version); + + return version_compare($client_version, '5.0.9', '>='); + } + else + { + return version_compare($client_version, '5.5.3', '>='); + } } } diff --git a/libraries/joomla/database/driver/mysqli.php b/libraries/joomla/database/driver/mysqli.php index 6815f9f3e8674..bde9b47ebc6d4 100644 --- a/libraries/joomla/database/driver/mysqli.php +++ b/libraries/joomla/database/driver/mysqli.php @@ -954,16 +954,24 @@ private function hasProfiling() private function serverClaimsUtf8mb4Support() { $client_version = mysqli_get_client_info(); + $server_version = $this->getVersion(); - if (strpos($client_version, 'mysqlnd') !== false) + if (version_compare($server_version, '5.5.3', '<')) { - $client_version = preg_replace('/^\D+([\d.]+).*/', '$1', $client_version); - - return version_compare($client_version, '5.0.9', '>='); + return false; } else { - return version_compare($client_version, '5.5.3', '>='); + if (strpos($client_version, 'mysqlnd') !== false) + { + $client_version = preg_replace('/^\D+([\d.]+).*/', '$1', $client_version); + + return version_compare($client_version, '5.0.9', '>='); + } + else + { + return version_compare($client_version, '5.5.3', '>='); + } } } diff --git a/libraries/joomla/database/driver/pdo.php b/libraries/joomla/database/driver/pdo.php index 6fa66bd65d3b2..81aabd9ea5262 100644 --- a/libraries/joomla/database/driver/pdo.php +++ b/libraries/joomla/database/driver/pdo.php @@ -325,7 +325,7 @@ public function disconnect() } $this->freeResult(); - unset($this->connection); + $this->connection = null; } /** diff --git a/libraries/joomla/database/driver/pdomysql.php b/libraries/joomla/database/driver/pdomysql.php index 851c617f8ec85..81d79548bb449 100644 --- a/libraries/joomla/database/driver/pdomysql.php +++ b/libraries/joomla/database/driver/pdomysql.php @@ -72,24 +72,21 @@ class JDatabaseDriverPdomysql extends JDatabaseDriverPdo */ public function __construct($options) { - /** - * Pre-populate the UTF-8 Multibyte compatibility flag. Unfortuantely PDO won't report the server version - * unless we're connected to it and we cannot connect to it unless we know if it supports utf8mb4 which requires - * us knowing the server version. Between this chicken and egg issue we _assume_ it's supported and we'll just - * catch any problems at connection time. - */ - $this->utf8mb4 = true; - // Get some basic values from the options. $options['driver'] = 'mysql'; - $options['charset'] = (isset($options['charset'])) ? $options['charset'] : 'utf8'; - if ($this->utf8mb4 && ($options['charset'] == 'utf8')) + if (!isset($options['charset']) || $options['charset'] == 'utf8') { $options['charset'] = 'utf8mb4'; } - $this->charset = $options['charset']; + /** + * Pre-populate the UTF-8 Multibyte compatibility flag. Unfortunately PDO won't report the server version + * unless we're connected to it, and we cannot connect to it unless we know if it supports utf8mb4, which requires + * us knowing the server version. Because of this chicken and egg issue, we _assume_ it's supported and we'll just + * catch any problems at connection time. + */ + $this->utf8mb4 = ($options['charset'] == 'utf8mb4'); // Finalize initialisation. parent::__construct($options); @@ -112,27 +109,42 @@ public function connect() } catch (\RuntimeException $e) { - // If the connection failed but not because of the wrong character set bubble up the exception - if (!$this->utf8mb4 || ($this->options['charset'] != 'utf8mb4')) + // If the connection failed, but not because of the wrong character set, then bubble up the exception. + if (!$this->utf8mb4) { throw $e; } - /** - * If the connection failed and I was trying to use the utf8mb4 charset then it is likely that the server - * doesn't support utf8mb4 despite claiming otherwise. - * - * This happens on old MySQL server versions (less than 5.5.3) using the mysqlnd PHP driver. Since mysqlnd - * masks the server version and reports only its own we can not be sure if the server actually does support - * UTF-8 Multibyte (i.e. it's MySQL 5.5.3 or later). Since the utf8mb4 charset is undefined in this case we - * catch the error and determine that utf8mb4 is not supported! - */ + /* + * Otherwise, try connecting again without using + * utf8mb4 and see if maybe that was the problem. If the + * connection succeeds, then we will have learned that the + * client end of the connection does not support utf8mb4. + */ $this->utf8mb4 = false; $this->options['charset'] = 'utf8'; parent::connect(); } + if ($this->utf8mb4) + { + /* + * At this point we know the client supports utf8mb4. Now + * we must check if the server supports utf8mb4 as well. + */ + $serverVersion = $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION); + $this->utf8mb4 = version_compare($serverVersion, '5.5.3', '>='); + + if (!$this->utf8mb4) + { + // Reconnect with the utf8 character set. + parent::disconnect(); + $this->options['charset'] = 'utf8'; + parent::connect(); + } + } + $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); }