diff --git a/system/Database/Database.php b/system/Database/Database.php index c2bc66d30d11..5fabda87d77c 100644 --- a/system/Database/Database.php +++ b/system/Database/Database.php @@ -13,6 +13,8 @@ namespace CodeIgniter\Database; +use CodeIgniter\Exceptions\ConfigException; +use CodeIgniter\Exceptions\CriticalError; use InvalidArgumentException; /** @@ -54,6 +56,8 @@ public function load(array $params = [], string $alias = '') throw new InvalidArgumentException('You have not selected a database type to connect to.'); } + assert($this->checkDbExtension($params['DBDriver'])); + $this->connections[$alias] = $this->initDriver($params['DBDriver'], 'Connection', $params); return $this->connections[$alias]; @@ -124,9 +128,9 @@ protected function parseDSN(array $params): array /** * Creates a database object. * - * @param string $driver Driver name. FQCN can be used. - * @param string $class 'Connection'|'Forge'|'Utils' - * @param array|object $argument The constructor parameter. + * @param string $driver Driver name. FQCN can be used. + * @param string $class 'Connection'|'Forge'|'Utils' + * @param array|ConnectionInterface $argument The constructor parameter or DB connection * * @return BaseConnection|BaseUtils|Forge */ @@ -138,4 +142,38 @@ protected function initDriver(string $driver, string $class, $argument): object return new $classname($argument); } + + /** + * Check the PHP database extension is loaded. + * + * @param string $driver DB driver + */ + private function checkDbExtension(string $driver): bool + { + $extensionMap = [ + // DBDriver => PHP extension + 'MySQLi' => 'mysqli', + 'SQLite3' => 'sqlite3', + 'Postgre' => 'pgsql', + 'SQLSRV' => 'sqlsrv', + 'OCI8' => 'oci8', + ]; + + $extension = $extensionMap[$driver] ?? ''; + + if ($extension === '') { + $message = 'Invalid DBDriver name: "' . $driver . '"'; + + throw new ConfigException($message); + } + + if (extension_loaded($extension)) { + return true; + } + + $message = 'The required PHP extension "' . $extension . '" is not loaded.' + . ' Install and enable it to use "' . $driver . '" driver.'; + + throw new CriticalError($message); + } }