__destruct(); self::$instance = NULL; } } /** * Initialize database. * * Set internal database and connectionproperties. Create Database object. Create PDO object and store it in the * Database object. * * @param string $host Database host. * @param string $user Database user name. * @param string $pass Database for user with $name password. * @param boolean $use_pconn Control use persistent connection to the database or not. * @param string $db Database name. * @param string $prefix Database tables prefix * @param boolean $force_charset Control force charset in conection or not. * @param string $encoding Contains connection encoding. Using only if $force_charset = true. */ public static function initialize($host, $user, $pass, $use_pconn, $db, $prefix, $force_charset = false, $encoding = 'utf8') { // Check PDO if (! extension_loaded('PDO')) { throw new Exception('PDO extension is not loaded'); } if (! extension_loaded('pdo_mysql')) { throw new Exception('pdo_mysql extension is not loaded'); } // Check if initialization if (! is_null(self::$instance)) { throw new Exception('Database already initialized'); } // Create database instance $instance = new Database(); // Set database and connection properties $instance->dbHost = $host; $instance->dbLogin = $user; $instance->dbPass = $pass; $instance->dbName = $db; $instance->dbEncoding = $encoding; $instance->tablesPrefix = $prefix; $instance->forceCharsetInConnection = $force_charset; $instance->usePersistentConnection = $use_pconn; // Create PDO object $instance->dbh = new PDO( "mysql:host={$instance->dbHost};dbname={$instance->dbName}", $instance->dbLogin, $instance->dbPass, array(PDO::ATTR_PERSISTENT => $instance->usePersistentConnection) ); if ($instance->forceCharsetInConnection) { $instance->dbh->exec("SET NAMES ".$instance->dbh->quote($instance->dbEncoding)); } // Store instance self::$instance = $instance; } /** * Forbid clone objects */ private final function __clone() {} /** * Forbid external object creation */ protected function __construct() {} /** * Handles errors * @param Exception $e */ protected function handleError(Exception $e){ if ($this->throwExceptions) { throw $e; } die($e->getMessage()); } /** * Set if exceptions must be process into the class or thrown. * @param boolean $value */ public function throwExeptions($value){ $this->throwExceptions = $value; } /** * Database class destructor. */ public function __destruct(){ foreach($this->preparedStatements as $key => $statement) { $this->preparedStatements[$key] = NULL; } $this->dbh = NULL; self::$instance = NULL; } /** * Executes SQL query. * In SQL query can be used PDO style placeholders: * unnamed placeholders (question marks '?') and named placeholders (like * ':name'). * If unnamed placeholders are used, $values array must have numeric indexes. * If named placeholders are used, $values param must be an associative array * with keys corresponding to the placeholders names * * Table prefix automatically substitute if table name puts in curly braces * * @param string $query SQL query * @param array $values Values, that must be substitute instead of * placeholders in SQL query. * @param array $params Array of query parameters. It can contains values with * following keys: * - 'return_rows' control if rows must be returned and how many rows must * be returnd. The value can be Database::RETURN_ONE_ROW for olny one row * or Database::RETURN_ALL_ROWS for all rows. If this key not specified, * the function will not return any rows. * - 'fetch_type' control indexes in resulting rows. The value can be * Database::FETCH_ASSOC for associative array, Database::FETCH_NUM for * array with numeric indexes and Database::FETCH_BOTH for both indexes. * Default value is Database::FETCH_ASSOC. * @return mixed If 'return_rows' key of the $params array is specified, * returns one or several rows (depending on $params['return_rows'] value) or * boolean false on fail. * If 'return_rows' key of the $params array is not specified, returns * boolean true on success or false on fail. * * @see Database::RETURN_ONE_ROW * @see Database::RETURN_ALL_ROWS * @see Database::FETCH_ASSOC * @see Database::FETCH_NUM * @see Database::FETCH_BOTH */ public function query($query, $values = NULL, $params = array()){ try{ $query = preg_replace("/\{(\w+)\}/", $this->tablesPrefix."$1", $query); $query_key = md5($query); if (! array_key_exists($query_key, $this->preparedStatements)) { $this->preparedStatements[$query_key] = $this->dbh->prepare($query); } $this->lastQuery = $query_key; // Execute query $this->preparedStatements[$query_key]->execute($values); // Check if error occurs if ($this->preparedStatements[$query_key]->errorCode() !== '00000') { $errorInfo = $this->preparedStatements[$query_key]->errorInfo(); throw new Exception(' Query failed: ' . $errorInfo[2]); } // No need to return rows if (! array_key_exists('return_rows', $params)) { return true; } // Some rows must be returned // Get indexes type if (! array_key_exists('fetch_type', $params)) { $params['fetch_type'] = Database::FETCH_ASSOC; } switch($params['fetch_type']){ case Database::FETCH_NUM: $fetch_type = PDO::FETCH_NUM; break; case Database::FETCH_ASSOC: $fetch_type = PDO::FETCH_ASSOC; break; case Database::FETCH_BOTH: $fetch_type = PDO::FETCH_BOTH; break; default: throw new Exception("Unknown 'fetch_type' value!"); } // Get results $rows = array(); if ($params['return_rows'] == Database::RETURN_ONE_ROW) { $rows = $this->preparedStatements[$query_key]->fetch($fetch_type); } elseif ($params['return_rows'] == Database::RETURN_ALL_ROWS) { $rows = $this->preparedStatements[$query_key]->fetchAll($fetch_type); } else { throw new Exception("Unknown 'return_rows' value!"); } $this->preparedStatements[$query_key]->closeCursor(); return $rows; } catch(Exception $e) { $this->handleError($e); } } /** * Returns value of PDOStatement::$errorInfo property for last query * @return string Error info array * * @see PDOStatement::$erorrInfo */ public function errorInfo(){ if (is_null($this->lastQuery)) { return false; } try{ $errorInfo = $this->preparedStatements[$this->lastQuery]->errorInfo(); } catch (Exception $e) { $this->handleError($e); } return $errorInfo; } /** * Returns the ID of the last inserted row * * @return int The ID */ public function insertedId(){ try{ $lastInsertedId = $this->dbh->lastInsertId(); } catch(Exception $e) { $this->handleError($e); } return $lastInsertedId; } /** * Get count of affected rows in the last query * * @return int Affected rows count */ public function affectedRows(){ if (is_null($this->lastQuery)) { return false; } try{ $affected_rows = $this->preparedStatements[$this->lastQuery]->rowCount(); } catch(Exception $e) { $this->handleError($e); } return $affected_rows; } } ?>