/** * Connect to the DB server * Throws an Exception on error */ public function __construct($conn = [], $pdo_attrs = []) { try { // PDO already connected if (empty($conn) and isset(self::$dbh) and get_class(self::$dbh) == 'PDO') { return TRUE; } if (empty($conn)) { // Handle default conn values (from settings) foreach (['host', 'port', 'name', 'user', 'pass', 'driver'] as $k) { $define = 'G_APP_DB_' . strtoupper($k); $this->{$k} = defined($define) ? constant($define) : NULL; } } else { // Inject connection info $this->host = $conn['host']; $this->user = $conn['user']; $this->name = $conn['name']; $this->pass = $conn['pass']; $this->port = $conn['port']; $this->driver = $conn['driver']; } $this->pdo_attrs = $pdo_attrs; $pdo_connect = $this->driver . ':host=' . $this->host . ';dbname=' . $this->name; if ($this->port) { $pdo_connect .= ';port=' . $this->port; } // PDO defaults $this->pdo_default_attrs = [PDO::ATTR_TIMEOUT => 30]; // Override the PDO defaults ? if (!is_null($this->pdo_attrs)) { foreach ($this->pdo_default_attrs as $key => $value) { if ($this->pdo_attrs[$key]) { $this->pdo_default_attrs[$key] = $this->pdo_attrs[$key]; unset($this->pdo_attrs[$key]); } } $this->pdo_attrs = $this->pdo_default_attrs + $this->pdo_attrs; } else { $this->pdo_attrs = $this->pdo_default_attrs; } // PDO hard overrides $this->pdo_attrs[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION; $this->pdo_attrs[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES 'UTF8'"; // Turn off PHP error reporting just for the connection here (invalid host names will trigger a PHP warning) $error_reporting = error_reporting(); error_reporting(0); // Note that PDO::ERRMODE_SILENT has no effect on connection. Connections always throw an exception if it fails self::$dbh = new PDO($pdo_connect, $this->user, $this->pass, $this->pdo_attrs); // Re-enable the error_reporting level error_reporting($error_reporting); // PDO emulate prepares if needed if (version_compare(self::$dbh->getAttribute(PDO::ATTR_SERVER_VERSION), '5.1.17', '<')) { self::$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); } self::$instance = $this; } catch (Exception $e) { self::$dbh = NULL; throw new DBException($e->getMessage(), 400); } }