As part of a fun project to help build my knowledge of PHP. I've written a Data Access Class here to bridge the site to the database. I know there are a lot of posts and articles out there explaining this type of thing, but I needed some individual feedback from people.
It does work, but I'm open to all sorts of responses! I'm torn between which format to work with, but I've been following Zend's code formatting documents. If you're familiar with that, I'd love to hear where my code is wrong there.
Any speed issues I'd gladly hear. I'm also open to code recycling tips.
class DataBase
{
/**
* @var null|\PDO
*/
private $_connection = NULL;
/**
* @var string
*/
private $_databaseHost = 'localhost';
/**
* @var string
*/
private $_databaseUser = 'root';
/**
* @var string
*/
private $_databasePassword = '';
/**
* @var string
*/
private $_returnMethod = 0;
const DECIDE_RETURN_METHOD = 0;
const ASSOC_ARRAY_RETURN_METHOD = 1;
const LAST_ID_RETURN_METHOD = 2;
const BOOLEAN_RETURN_METHOD = 3;
/**
* Construct a Database object. Use this to query the database(s).
*
* @param string $database The database to start a MySQL connection with.
* @param string $host The host the connection will be with.
* @param string $username The username the connection will be with.
* @param string $password The password the connection will be with.
*
* @throws Exception If the database could not be connected to.
*/
public function __construct($database, $host = 'localhost', $username = 'root', $password = '')
{
$this->_databaseHost = $host;
$this->_databaseUser = $username;
$this->_databasePassword = $password;
try {
$dsn = 'mysql:dbname=' .$database. ';host=' .$this->_databaseHost;
$this->_connection = new PDO($dsn, $this->_databaseUser, $this->_databasePassword,array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
} catch (PDOException $error) {
throw new Exception('Could not connect to ' .$database. '.<br>' .$error->getMessage());
}
}
/**
* Execute a string of SQL to the database.
*
* @param string $sql The SQL to be executed.
* @param array|null $data Optional data to be prepared for the SQL staement.
* @param int $return Use DECIDE_RETURN_METHOD if you're using a common sql statement, and it will choose what it thinks is the
* best return method. Or choose ASSOC_ARRAY_RETURN_METHOD for an associative array to be returned, BOOLEAN_RETURN_METHOD for a boolean,
* or LAST_ID_RETURN_METHOD for the last inserted ID. If the last method is used, you may specify $data['lastInsertId'] to give
* a value for lastInsertId().
*
* @return mixed Corresponds to the parameter: $return.
*/
public function PerformDBQuery($sql, array $data = NULL, $return=self::DECIDE_RETURN_METHOD)
{
if ($return == 0) {
if (stripos($sql, 'select') > -1) {
$this->_returnMethod = self::ASSOC_ARRAY_RETURN_METHOD;
} elseif (stripos($sql, 'insert') > -1 || stripos($sql, 'update') > -1 || stripos($sql, 'delete') > -1) {
$this->_returnMethod = self::BOOLEAN_RETURN_METHOD;
}
} elseif ($return > 0 && $return < 4) {
$this->_returnMethod = $return;
}
return $this->query_db($sql, $data);
}
/**
* Execute a string of SQL to the database.
*
* @param string $sql The SQL to be executed.
* @param array|null $data Optional data to be prepared for the SQL staement.
*
* @throws Exception If the sql statement is not a minimum 10 character string.
* @throws Exception If the database is not connected.
*
* @return mixed Corresponds to $this->_returnMethod.
*/
private function query_db($sql, array $data)
{
if (is_string($sql) && isset($sql[9])) {
if (!is_null($this->_connection)) {
try {
if (is_null($data)) {
$statement = $this->_connection->query($sql);
} else {
$statement = $this->_connection->prepare($sql);
$statement->execute($data);
}
if ($this->_returnMethod == 1) {
return $statement->fetchAll(PDO::FETCH_ASSOC);
} elseif ($this->_returnMethod == 2) {
if (isset($data['lastInsertId'])) {
$column = $data['lastInsertId'];
} else {
$column = NULL;
}
return $this->_connection->lastInsertId($column);
} elseif ($this->_returnMethod == 3) {
return TRUE;
}
} catch (PDOException $error) {
if ($this->_returnMethod == 1 || $this->_returnMethod == 2) {
return NULL;
} elseif ($this->_returnMethod == 3) {
return FALSE;
}
}
} else {
throw new Exception('Database connection not available.');
return FALSE;
}
} else {
throw new Exception('Invalid SQL string.');
return FALSE;
}
}
}
If it's possible, I'd like an opinion on how to organize errors and exceptions!
- Do I throw errors in this class?
- Should I use Exceptions, or should I
return
the error message from the class?
I have yet to find an article explaining standards for error handling in this situation. I've been researching when to use self::
and $this->
and I'd like to know if I'm using those right.