Created
February 9, 2012 22:22
-
-
Save tkdave/1783826 to your computer and use it in GitHub Desktop.
Memcache-backed MySQL Database connection class.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Lazy Database connection class - API version | |
* | |
* The database is not actually opened until we execute a query | |
* | |
* @author David Knape | |
*/ | |
class DBConnection | |
{ | |
public $databaseHost = "localhost"; | |
public $databaseUser = "root"; | |
public $databasePass = ""; | |
public $databaseName = ""; | |
protected $connected = false; | |
protected $memcache; | |
protected $memcacheHost; | |
protected $memcachePort; | |
protected $memcacheConnected = false; | |
public $debugLogEnabled = false; | |
public $debugLogFile = "/tmp/dbconnection.log"; | |
/** | |
* Creates a new database connection | |
* | |
* @param $db_host | |
* @param $db_name | |
* @param $db_user | |
* @param $db_pass | |
* @param $memcache_host | |
* @param $memcache_port | |
*/ | |
public function __construct($db_host = "localhost", $db_name = "", $db_user = "root", $db_pass = "", $memcache_host = "", $memcache_port = 11211) | |
{ | |
$this->databaseHost = $db_host; | |
$this->databaseUser = $db_user; | |
$this->databasePass = $db_pass; | |
$this->databaseName = $db_name; | |
$this->memcacheHost = $memcache_host; | |
$this->memcachePort = $memcache_port; | |
} | |
public function __wakeup() | |
{ | |
$this->connected = false; | |
$this->memcacheConnected = false; | |
} | |
public function isConnected() | |
{ | |
return $this->connected; | |
} | |
public function getDateTimeString($date_string) | |
{ | |
return date('Y/M/d h:m:s', strtotime($date_string)); | |
} | |
/** | |
* Runs DB Query using mysql function | |
* | |
* Returns results as an array of objects. | |
* Optional param ('explicitType') is used to pass a class type to AMF | |
* | |
* @access private | |
*/ | |
public function query($sql, $ignoreError = false, $explicitType = "") | |
{ | |
$rs = $this->execute($sql, $ignoreError); | |
$results = array(); | |
if (is_resource($rs)) { | |
while ($row = mysql_fetch_array($rs, MYSQL_ASSOC)) { | |
// convert ints and float to actual ints and floats | |
$col_n = 0; | |
foreach ($row as $col => $val) { | |
switch (mysql_field_type($rs, $col_n)) { | |
case 'int': | |
$row[$col] = (int)$val; | |
break; | |
case 'real': | |
$row[$col] = (float)$val; | |
break; | |
} | |
$col_n++; | |
} | |
$obj = (object)$row; | |
if ($explicitType) $obj->_explicitType = $explicitType; | |
$results[] = $obj; | |
} | |
} | |
//if(count($results)==1) return $results[0]; | |
return $results; | |
} | |
/** | |
* Default cache time - 60 minutes (3600 seconds) | |
*/ | |
public function queryCached($sql, $seconds = 3600, $explicitType = null) | |
{ | |
if (!$this->memcacheConnected && $this->memcacheHost && $this->memcachePort) { | |
$this->connectMemcache(); | |
} | |
$key = MD5($this->databaseHost . '_' . $this->databaseName . '_' . $this->databaseUser) . '_' . MD5($sql); | |
if ($this->memcacheConnected) { | |
$result = $this->memcache->get($key); | |
} | |
if (!$result) { | |
$result = $this->query($sql, false, $explicitType); | |
if ($this->memcacheConnected) { | |
$this->memcache->set($key, $result, MEMCACHE_COMPRESSED, $seconds); | |
} | |
} | |
return $result; | |
} | |
/** | |
* Shortcut to return first record | |
* | |
* @param $sql | |
* @param $ignoreError | |
* @param $explicitType | |
*/ | |
public function getOne($sql, $ignoreError = false, $explicitType = "") | |
{ | |
return @array_shift($this->query($sql, $ignoreError, $explicitType)); | |
} | |
/** | |
* Execute a query and return mysql resource on success | |
* | |
* Throws an exception on errors unless ignoreError is true | |
*/ | |
public function execute($sql, $ignoreError = false) | |
{ | |
if (!$this->connected) $this->connect(); | |
$this->trace("[DBConnection] execute: " . $sql); | |
$rs = mysql_query($sql); | |
if (!$rs) { | |
if ($ignoreError !== true) throw new Exception(mysql_error()); | |
return false; | |
} else { | |
return $rs; | |
} | |
} | |
public function connect() | |
{ | |
if ($this->connected) return; | |
$this->connected = @mysql_connect($this->databaseHost, $this->databaseUser, $this->databasePass) && @mysql_select_db($this->databaseName); | |
// try again in 1 second | |
if (!$this->connected) { | |
sleep(1); | |
$this->connected = @mysql_connect($this->databaseHost, $this->databaseUser, $this->databasePass) && @mysql_select_db($this->databaseName); | |
} | |
if (!$this->connected) { | |
$this->trace("[DBConnection] Failed to Connect"); | |
throw new Exception("Unable to connect to the database {$this->databaseName} at {$this->databaseHost}"); | |
} | |
} | |
/** | |
* Initialize memcache connection | |
*/ | |
protected function connectMemcache() | |
{ | |
$host = $this->memcacheHost; | |
$port = $this->memcachePort; | |
$this->memcacheConnected = false; | |
// init memcache | |
if (@class_exists('Memcache') && $host != null && $port != null) { | |
$this->memcache = new Memcache(); | |
if (@$this->memcache->connect($host, $port)) { | |
$this->memcacheConnected = true; | |
} else if (@$this->memcache->connect($host, $port)) { | |
// try again to avoid intermittent connection issues | |
$this->memcacheConnected = true; | |
} | |
} | |
} | |
protected function trace($s) | |
{ | |
if (!$this->debugLogEnabled) return; | |
if (!file_exists($this->debugLogFile)) { | |
touch($this->debugLogFile); | |
} | |
$fh = @fopen($this->debugLogFile, 'a'); | |
if (is_resource($fh)) { | |
fwrite($fh, "$s\n"); | |
fclose($fh); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment