This is a work in progress, but should give you some food for thought. (Mainly I just need to decide how I want to handle various potential error situations.) This makes use of the singleton pattern.
Mysql.class.php:
<?php
/**
* Mysql.class.php
* @author Charles Reace (www.charles-reace.com)
* @version 1.0
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*/
/**
* class used for db query results
*/
require_once 'QueryResult.class.php';
/**
* "Singleton" pattern MySQL database class
* @package Database
*/
class Mysql
{
// USER MODIFIABLE DATABASE SETTINGS //
private $dbHost = 'localhost';
private $dbUser = 'dbuser';
private $dbPwd = 'password123';
private $database = 'database_name';
private $connx = NULL;
private $error = '';
// DO NOT MODIFY BELOW THIS LINE //
private static $instance;
/**
* Private constructor: prevents direct creation of object
*/
private function __construct()
{
$this->connect();
}
/**
* Singleton method (only allow one instance of this class)
* @return object
*/
public static function singleton()
{
if (!isset(self::$instance))
{
$c = __CLASS__;
self::$instance = new $c;
}
return self::$instance;
} // end singleton()
/**
* Prevent users from cloning this instance
* @return void
*/
public function __clone()
{
trigger_error('Clone is not allowed.', E_USER_ERROR);
}
/**
* Connect to MySQL and select database
* @return boolean
*/
private function connect()
{
$connx = @mysql_connect($this->dbHost, $this->dbUser, $this->dbPwd);
if($connx != FALSE)
{
$this->connx = $connx;
$db = mysql_select_db($this->database, $this->connx);
if($db == FALSE)
{
$this->error = "Unable to select DB: " . mysql_error();
user_error($this->error, E_USER_WARNING);
return(FALSE);
}
return(TRUE);
}
$this->error = "Unable to connect to DBMS: " . mysql_error();
user_error($this->error, E_USER_WARNING);
return(FALSE);
} // end connect()
/**
* Get database connection resource ID
* @return resource
*/
public function getConnection()
{
return($this->connx);
}
/**
* Sanitize input for use in SQL
* @param string|integer|float $input
* @return string|integer|float
*/
public function sanitize($input)
{
$input = trim($input);
if(!is_numeric($input))
{
if(get_magic_quotes_gpc())
{
$input = stripslashes($input);
}
$input = "'" . mysql_real_escape_string($input) . "'";
}
return($input);
}
/**
* Execute SELECT query (or any query that returns result rows)
* @param string $sql
* @return object
*/
public function select($sql)
{
if(!$this->connx)
{
$this->error = "Cannot process query, no DB connection.";
user_error($this->error, E_USER_WARNING);
return(FALSE);
}
$result = mysql_query($sql, $this->connx);
if($result)
{
if(mysql_num_rows($result))
{
return(new QueryResult($result, $this->connx));
}
else
{
return(0);
}
}
else
{
$this->error = "Query failed ($sql): " . mysql_error();
user_error($this->error, E_USER_WARNING);
return(FALSE);
}
}
/**
* Execute query that does not return result rows (e.g.: INSERT)
* @param string $sql
* @return integer
*/
public function modify($sql)
{
if(!$this->connx)
{
$this->error = "Cannot process query, no DB connection.";
user_error($this->error, E_USER_WARNING);
return(FALSE);
}
$result = mysql_query($sql, $this->connx);
if($result)
{
return(mysql_affected_rows($this->connx));
}
else
{
$this->error = "Query failed ($sql): " . mysql_error();
user_error($this->error);
return(FALSE);
}
}
}
QueryResult.class.php:
<?php
/**
* Mysql.class.php
* @author Charles Reace (www.charles-reace.com)
* @version 1.0
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*/
/**
* Query result from Mysql class
* @package Database
*/
class QueryResult
{
private $result = NULL;
private $connx = NULL;
private $numRows = 0;
/**
* Constructor
* @param resource $result
* @param resource $connx
* @return void
*/
public function __construct($result, $connx)
{
$this->result = $result;
$this->connx = $connx;
$this->numRows = mysql_num_rows($result);
}
/**
* Get specified result row as assoc. array
* @param integer $row
* @return array
*/
public function getRow($row = NULL)
{
if($row !== NULL and is_numeric($row))
{
if(mysql_data_seek($this->result, abs((int)$row)))
{
return(mysql_fetch_assoc($this->result));
}
}
else
{
return(false);
}
} // end getRow()
/**
* Get query results as HTML table.
* If $headers evaluates a TRUE, a header row will be included.
* If $headers is TRUE and the $labels is an array, the values in $labels
* will be used as the column heading labels.
* @param boolean $headers
* @param array $labels
* @return string
*/
public function getTable($headers = FALSE, $labels = NULL)
{
if(!mysql_data_seek($this->result, 0))
{
return(false);
}
$table = "<table class='dbresult'>\n";
if($headers)
{
$table .= "<tr>";
if(is_array($labels))
{
foreach($labels as $label)
{
$table .= "<th>$label</th>";
}
}
else
{
$num = mysql_num_fields($this->result);
for($ix = 0; $ix < $num; $ix++)
{
$table .= "<th>".mysql_field_name($this->result,$ix)."</th>";
}
}
$table .= "</tr>\n";
}
while($row = mysql_fetch_row($this->result))
{
$table .= "<tr>";
foreach($row as $val)
{
$table .= "<td>$val</td>";
}
$table .= "</tr>\n";
}
$table .= "</table>\n";
return($table);
}
/**
* Get query results as an array
* @return array
*/
public function getArray()
{
mysql_data_seek($this->result, 0);
$data = array();
while($row = mysql_fetch_assoc($this->result))
{
$data[] = $row;
}
return($data);
} // end getArray()
/**
* Get query results as an XML string
* @return string
*/
public function getXml()
{
mysql_data_seek($this->result, 0);
$xml = "<?xml version='1.0' encoding='ISO-8859-1'?>\n<data>\n";
$count = 1;
while($row = mysql_fetch_assoc($this->result))
{
$xml .= " <record row='$count'>\n";
foreach($row as $key => $val)
{
$xml .= " <$key>$val</$key>\n";
}
$xml .= " </record>\n";
$count++;
}
$xml .= "</data>";
return($xml);
} // end getXml()
/**
* Free this MySQL result
* @return boolean
*/
public function free()
{
return(mysql_free_result($this->result));
} // end free()
/**
* Getter for query result resource ID
* @return resource
*/
public function getResultId()
{
return($this->result);
}
/**
* Getter for number of result rows
* @return integer
*/
public function getNumRows()
{
return($this->numRows);
}
} // end class QueryResult
Sample usage:
<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
require_once 'Mysql.class.php';
class Test
{
private $db;
public function __construct()
{
$this->db = Mysql::singleton();
}
public function listCustomers()
{
$result = $this->db->select('SELECT * FROM customers');
return $result->getTable(true);
}
}
$test = new Test();
echo $test->listCustomers();