Simple (secure) database object
Posted October 30th, 2007 by zeger
When using JSON as a data transport encoding schema for MySQL the database server should always return a single row; it can be useful (even better: you should) to make use of stored functions for the generation of the JSON data on the database side. A simple database object is shown and discussed.
Note:
Article is still wip.
Firstly note that we should use constants wherever possible; in this example constants are set in the constants.php file.
The object has some specific properties:
-
public function __construct()
Upon construction the database object "auto-connects" to the database; usually the database object is instantiated in order to communicate with the database hence we auto connect. -
public function connect()
We use the new mysqli object to connect to the database in some occasions a stored procedure is implemented which can only be used when the mysqli object is used to connect. For example: Stored procedures are used when recursively constructing a menu tree.Note we only use constants to connect to the database: this is good practice and improves the development process of database driven applications.
-
public function escapeString( $value )
A function to escape the SQL string is needed, we can write it ourselfs or use themysqli_real_escape_stringfunction which should solve all our escaping problems. Note the function needs a database link object. -
public function callFunction( $function_name )
This object can be used for stored functions, in order to improve the security we always escape the function arguments. By usingarray_walkwe can escape all function arguments without any hassle by using the previously describedescapeStringfunction.
The complete object is shown below.
require_once( $_SERVER['DOCUMENT_ROOT'] . '/constants.php' ); class Database { private $link; public function __construct() { $this->connect(); } public function connect() { /** * We could use some round robin here for load balancing */ $link = mysqli_connect( DATABASE_HOST, DATABASE_USER, DATABASE_PASSWORD, DATABASE_SCHEMA, DATABASE_PORT ); if ( !$link ) die( 'Could not connect: ' . $link->error ); $this->link = $link; } public function reconnect() { $this->cleanUp(); $this->connect(); } public function getLink() { return $this->link; } public function cleanUp() { mysqli_close( $this->link ); } public function getError() { return $this->link->error; } public function query( $sql ) { $call_result = $this->link->query( $sql ); if ( $call_result !== false && $this->link->affected_rows ) { /** * For stored procedures the result can be empty * hence the call result is 'true' and no rows can * be fetched */ if ( $call_result === true ) return true; $row = $call_result->fetch_row(); return $row; } return false; } public function escapeString( $value ) { /** * mysqli_real_escape_string should protect for * SQL injection */ return mysqli_real_escape_string( $this->link, $value ); } /** * Secure function call * * Call SELECT function_name( arg_1 ... arg_n ) and * return the result * * @param String $function_name * @return array */ public function callFunction( $function_name ) { $parameters = func_get_args(); array_shift( $parameters ); array_walk( $parameters, array( $this, 'escapeString' ) ); $sql = 'SELECT ' . $function_name . "( '" . implode( "','" , $parameters ) . "' );"; return $this->query( $sql ); } }
www.zeger.nl