I've written this DB Handler class. Please review it and suggest any code edits or point out mistakes and security loop holes. Please also suggest a better way to handle things, if there is a security loop hole in there.
class db {
protected $dbHost;
protected $dbUser;
protected $dbPass;
protected $dbName;
protected $dbLink;
public function __construct ( $host=NULL, $user=NULL, $pass=NULL, $db=NULL ){
$this->dbHost = $host? $host : 'localhost';
$this->dbUser = $user? $user : 'root';
$this->dbPass = $pass? $pass : '';
$this->dbName = $db? $db : 'my_db_name';
if( !($this->dbLink = mysqli_connect( $this->dbHost, $this->dbUser, $this->dbPass, $this->dbName) ) ){
echo 'Error While Connection to DB: '.mysqli_error( $this->dbLink );
}
}
public function __destruct(){
if( ! mysqli_close($this->dbLink) ){
echo 'Error While Closing Connection to DB: '.mysqli_error( $this->dbLink );
}
}
/********************************************************************************
1) This function is used to fetch data
@param: $tableName [required]
@param: $requiredColumns. This is an array like 'tableColumn', 'tableColumn', 'tableColumn'
@param: $conditionsArray. This is an associative array like 'tableColumn' => 'value to check'
@param: $orderBy. This is an array like 'tableColumn', 'ASC'
*********************************************************************************/
public function select( $tableName, $requiredColumns = NULL, $conditionsArray = NULL, $orderBy = NULL ){
if( $requiredColumns == NULL || count($requiredColumns) <= 0 ){
$col = '*';
}
else{
$col = implode(', ', $requiredColumns);
}
$query = 'SELECT '.$col.' FROM `'.$tableName.'`';
if( $conditionsArray != NULL ){
$args = array();
foreach( $conditionsArray as $key => $value ){
array_push( $args , '`'.$key.'` = "'.$value.'"' );
}
//var_dump( $args );
$where = implode( ' AND ' , $args );
$query .= ' WHERE ' . $where;
}
if( $orderBy != NULL ){
$order = implode(' ', $orderBy);
$query .= 'ORDER BY '.$order;
}
//echo $query;
return $this->execute( $query , 'resource' );
}
/********************************************************************************
2) This function is used to insert record
@param: $tableName [required]
@param: $data [required] This is an associative array like 'tableColumn' => 'value to insert'
*********************************************************************************/
public function insert( $tableName, $data ){
if( $data != NULL && count($data) > 0 ){
$cols = ''; $vals = '';
foreach( $data as $key => $val ){
$cols .= $key.', ';
$vals .= "'".$val."', ";
}
$cols = rtrim( $cols , ", ");
$vals = rtrim( $vals , ", ");
$query = "INSERT INTO `".$tableName."` (".$cols.") VALUES (".$vals.")";
return $this->execute( $query, true ) ;
}
}
/********************************************************************************
3) This function is used to Update records
@param: $tableName [required]
@param: $data [required] This is an associative array like 'tableColumn' => 'value to insert'
@param: $conditionsArray. This is an associative array like 'tableColumn' => 'value to check'
*********************************************************************************/
public function update( $tableName, $data, $conditionsArray ){
if( $data != NULL && count($data) > 0 ){
$args = array();
foreach( $data as $key => $value ){
array_push( $args , '`'.$key.'` = "'.$value.'"' );
}
$dataString = implode( ', ' , $args );
$arr = array();
foreach( $conditionsArray as $key => $value ){
array_push( $arr , '`'.$key.'` = "'.$value.'"' );
}
$where = implode( ' AND ' , $arr );
$query = 'UPDATE `'.$tableName.'` SET '.$dataString.' WHERE '.$where;
return $this->execute( $query );
}
}
/********************************************************************************
4) This function is used to check number of records
@param: $tableName [required]
@param: $conditionsArray. This is an associative array like 'tableColumn' => 'value to check'
*********************************************************************************/
public function numRows( $tableName, $conditionsArray = NULL ){
if( $conditionsArray == NULL ){
$query = 'SELECT 1 FROM '.$tableName;
}
else{
$args = array();
foreach( $conditionsArray as $key => $value ){
array_push( $args , '`'.$key.'` = "'.$value.'"' );
}
//var_dump( $args );
$where = implode( ' AND ' , $args );
$query = 'SELECT 1 FROM `'.$tableName.'` WHERE ' . $where;
}
//echo $query;
$resource = $this->execute( $query , 'resource' );
return mysqli_num_rows( $resource );
}
/********************************************************************************
5) This function is used to DELETE
@param: $tableName [required]
@param: $conditionsArray [required] This is an associative array like 'tableColumn' => 'value to check'
*********************************************************************************/
public function delete( $tableName, $conditionsArray ){
if( $conditionsArray != NULL ){
$args = array();
foreach( $conditionsArray as $key => $value ){
array_push( $args , '`'.$key.'` = "'.$value.'"' );
}
//var_dump( $args );
$where = implode( ' AND ' , $args );
$query = 'DELETE FROM `'.$tableName.'` WHERE ' . $where;
}
return $this->execute( $query );
}
/********************************************************************************
6) This function is used to login
@param: $tableName [required]
@param: $conditionsArray. This is an associative array like 'tableColumn' => 'value to check'
*********************************************************************************/
public function login( $user, $pass ){
$user = mysqli_real_escape_string( $this->dbLink, $user );
$pass = mysqli_real_escape_string( $this->dbLink, $pass );
$data = array( 'username' => $user, 'password' => md5($pass) );
if( $this->numRows( 'users' , $data ) > 0 ){
$result = $this->select( 'users' , NULL , $data );
return mysqli_fetch_assoc( $result );
}
else{
return NULL;
}
}
/********************************************************************************
7) This function is used to perform custom query
@param: $query [required]
*********************************************************************************/
public function query( $query ){
return $this->execute( $query );
}
/********************************************************************************
8) This function is used to execute the queries
@param: $query [required]
@param: $return_type = 'bool' , 'resource' , 'id'
*********************************************************************************/
private function execute( $query , $return_type = 'bool' ){
if( !empty($query) ){
switch( $return_type ){
case 'id' :
if( mysqli_query( $this->dbLink , $query ) ){
return mysqli_insert_id( $this->dbLink );
}
else{
die(mysqli_error( $this->dbLink ));
return 0;
}
break;
case 'resource' :
if( $rs = mysqli_query( $this->dbLink , $query ) ){
return $rs;
}
else{
die(mysqli_error( $this->dbLink ));
return false;
}
break;
case 'bool' :
if( mysqli_query( $this->dbLink , $query ) ){
return true;
}
else{
die(mysqli_error( $this->dbLink ));
return false;
}
break;
default :
echo 'Invalid 2nd parameter (return format)';
break;
}
}
else{
echo 'Empty query not allowed.';
}
}
}
var_dump
to leak your database credentials. \$\endgroup\$$this->dbLink = mysqli_connect( $this->dbHost, $this->dbUser, $this->dbPass, $this->dbName)
I'm storing the connection info indbLink
and using this variable in almost every method below sir. \$\endgroup\$$this->dbHost = $host ? $host : 'localhost';
, and the same for username, password, and DB name. Once you've connected, you no longer need that info; you only needed it in the first place to build$this->dbLink
. \$\endgroup\$right
:| I think I should make local variable inconstructor
for this purpose. \$\endgroup\$public function __construct($host='localhost', $user='root', $pass='', $db='my_db_name')
. (Though frankly, it'd be better to not have defaults at all. That's per-app configuration info, and belongs in a config file. And with default values, that opens up the possibility of only specifying half the settings, which wouldn't make sense.) \$\endgroup\$