db-class.php
//cms-settings.php contains various CMS global settings such as the database //username, password, and server. This file is created by the installation //script. require('cms-settings.php'); //QueryResult represents a single query //This class wraps the MySQL functions that handle queries class QueryResult { //Resource handle to the MySQL query var $result; function QueryResult($res) { this->$result = $res; } function FetchArray($result_type = MYSQL_BOTH) { return mysql_fetch_array(this->$result, $result_type); } function FetchAssoc() { return mysql_fetch_assoc(this->$result); } function FetchRow() { return mysql_fetch_row(this->$result); } function FetchField() { return mysql_fetch_field(this->$result); } function FetchLengths() { return mysql_fetch_lengths(this->$result); } function FetchObject() { return mysql_fetch_object(this->$result); } function FieldFlags($offset) { return mysql_field_flags(this->$result, $offset); } function FieldLength($offset) { return mysql_field_len(this->$result, $offset); } function FieldFlags($index) { return mysql_field_name(this->$result, $index); } function FieldSeek($offset) { return mysql_field_seek(this->$result, $offset); } function FieldType($offset) { return mysql_field_type(this->$result, $offset); } function FreeResult() { mysql_free_result(this->$result); } } //Database represents a connection to a SQL database class Database { //Holds the most recent error var $error; //Resource handle for the database connection var $link; function Database() { this->$error = ""; this->$link = false; } //Connects to the CMS's database using the global database information //so that no module need know any of this information function Connect() { global $dbserver, $dbusername, $dbpassword, $dbname; this->$link = mysql_connect($dbserver, $dbusername, $dbpassword); if (!this->$link) { this->$error = mysql_error(); } else if (!mysql_select_db($dbname, this->$link)) { this->$error = mysql_error(); } } function Disconnect() { mysql_close(this->$link); } //Performs a query //It is assumed that the query is not already safe from SQL-injection and so //Query() attempts to make the query safe for use function Query($query) { if (!is_numeric($query)) { $query = mysql_real_escape_string($query, this->$link); } $result = mysql_query($query, this->$link); if (!$result) { this->$error = mysql_error(); return false; } else { this->$error = ""; return new QueryResult($result); } } //Wraps the creation of a table for a module //All modules should use this function to create tables function CreateTable($module_name, $table_name, $columns) { return this->Query("CREATE TABLE " . this->GetTableName($module_name, $table_name) . " " . $columns); } //Provides a means of creating a unique name for any module's tables //Modules should always use this function to reference their tables and the //tables of other modules function GetTableName($module_name, $table_name) { return $module_name . "_" . $table_name; } }?>
I've broken the DB class into two separate classes since it seemed more logical to have the DB class manage access to the DB while playing with the results of a query seemed to be a completely different beast. I am aware that it is possible for modules to create tables that dont follow my naming convention but I'm hoping that if anybody besides myself ever does write modules then they'll do The Right Thing.
Excerpt from index.php
//Ensures that the $_REQUEST array has had its slashes strippedfunction GetRequestVars() { $fixed = array(); if (!get_magic_quotes_gpc()) { $fixed = $_REQUEST; } else { foreach ($_REQUEST as $key => $value) { $fixed[$key] = stripslashes($value); } } return $fixed;}
This function is required so that when passing data to Database::Query() strings dont get escaped twice. I am unsure if the key to $_REQUEST is also escaped so I'll need to test that since it's possible that keys might also be used in a query.