Log in

View Full Version : Introducing Safety to PHP/MySQL



shotgun_ninja
06-02-2008, 04:20 PM
Hi again,

I've been scratching my head about how to make MySQL submissions in PHP more organized by results and such, and not leaving any connection objects open, keeping my username and password private, etc... So I decided to create a layer for safe, secure connection objects using PHP 5.X's object-orienting system. I call it MySAFE, or MySQL Secure Access For Everyone.

Here is some of the code:

File: mysafe.php


<?php session_start();

include("cfg.php");

if (!isset($_SERVER["conn"])) {
$_SERVER["conn"] = array();
}

function mysafe_connect() {
mysafe_unlock();
$id = count($_SERVER["conn"]);
$_SERVER["conn"][$id] = mysql_connect($_ENV["host"], $_ENV["user"], $_ENV["pass"]);
if (!$_SERVER["conn"][$id]) { mysafe_lock(); return NULL; }
$flusher = mysql_connect();
if ($flusher) { mysql_close($flusher); }
if (!mysql_select_db($_ENV["db"], $_SERVER["conn"][$id])) { mysafe_lock(); return NULL; }
mysafe_lock();
return $id;
}

function mysafe_query($query, $id) {
$query = mysql_real_escape_string($query);
$violations = 0;
$blacklist = array("create", "drop", "alter", "delete", "grant", "rename", "revoke", "set password", "cache index", "flush", "kill", "reset", "master", "slave", "show", "load", "\'=\'\'", "`=``", "\"=\"\"");
foreach ($list as $k => $v) {
if (stripos($query, $v) !== false) { $violations = $violations + 1; }
}
if ($violations >= 1) {
if (/* Get admin status */) { return mysql_query($query, $_SERVER["conn"][$id]); }
} else { return mysql_query($query, $_SERVER["conn"][$id]; }
}

function mysafe_close($id) {
$ok = mysql_close($_SERVER["conn"][$id]);
unset($_SERVER["conn"][$id]);
return $ok;
}

?>

File: cfg.php


<?php session_start();

function mysafe_unlock() {
/******** CHANGE DURING INSTALL ********/
$_ENV["host"] = "localhost";
$_ENV["user"] = "username";
$_ENV["pass"] = "password";
$_ENV["db"] = "default_db";
/******** END CHANGES HERE ********/
}

function mysafe_lock() {
unset($_ENV["host"]);
unset($_ENV["user"]);
unset($_ENV["pass"]);
unset($_ENV["db"]);
}

?>


File: base.php


<?php session_start();

include("mysafe.php");

class Result {
function __construct($id, $table) {
$this->valid = true;
$this->id = $id;
$this->table = $table;
$this->query = "SELECT * FROM `".$table."` WHERE `id`=".$id." LIMIT 1";
/* NOTE: In the above query line, replace `id` with the backquoted name of your primary key column. */
mysafe_unlock();
if (!$this->conn = mysafe_connect())
{ $this->valid = false; mysafe_lock(); }
if (!$this->result = mysafe_query($this->query, $this->conn))
{ mysafe_close($this->conn); $this->valid = false; mysafe_lock(); }
if (!$this->values = mysql_fetch_assoc($this->result))
{ mysafe_close($this->conn); $this->valid = false; mysafe_lock(); }
mysafe_close($this->conn);
mysafe_lock();
}

function is_valid() { return $this->valid; }
function get_id() { return $this->id; }
function get_table() { return $this->table; }
function get_typename() { return "Result"; } /* Just for differentiating. */
protected function get_result_value($name) {
if (!$this->is_valid) { return NULL; }
if (!isset($this->values[$name])) { return NULL; }
else { return $this->values[$name]; }
}
protected function get_result_names()
{
if (!$this->valid) { return NULL; }
$ret = array();
foreach ($this->values as $name => $value) {
$ret = array_push($ret, $name);
}
return $ret;
}
protected function set_result_value($name, $value)
{
if (!$this->valid) { return NULL; }
if ($name == "id") { return NULL; }
$query = "UPDATE `".$this->table."` SET `".$name."`=".$value." WHERE `id`=".$this->id." LIMIT 1";
mysafe_unlock();
if (!$this->conn = mysafe_connect())
{ mysafe_lock(); return mysql_error(); }
if (!$ret = mysafe_query($query, $this->conn)) { mysafe_close($this->conn); mysafe_lock(); return mysql_error()."[[$query]]"; }
else { mysafe_close($this->conn); mysafe_lock(); return $ret; }
}
protected $id;
protected $conn;
protected $result;
protected $values;
protected $valid;
protected $table;
protected $query;
}

class ResultList extends Result {
function __construct($count, $page, $order, $table) {
$this->valid = true;
$this->order = $order or NULL;
$this->count = $count;
if ($page > 0) { $this->page = $page; } else { $this->page = 1; }
$this->table = $table;
$this->query = "SELECT * FROM `".$table."`";
if ($this->count != NULL) {
$this->start = $count * ($page - 1);
$this->end = ($count * $page) - 1;
$this->query = $this->query." WHERE `id` > ".$this->start." AND `id` < ".$this->end." LIMIT ".$this->count;
}
if ($this->order) {
$this->query = $this->query." ORDER BY `".$this->order."`";
}
mysafe_unlock();
if (!$this->conn = mysafe_connect())
{ $this->valid = false; mysafe_lock(); }
if (!$this->result = mysafe_query($this->query, $this->conn))
{ mysafe_close($this->conn); $this->valid = false; mysafe_lock(); }
$this->count = mysql_num_rows($this->result);
$this->end = $this->start + $this->count - 1;
mysafe_close($this->conn);
mysafe_lock();
}
function get_id() {}
function get_count() { return $this->count; }
function get_page() { return $this->page; }
function get_start() { return $this->start; }
function get_end() { return $this->end; }
function get_order() { return $this->order; }
function get_typename() { return "ResultList"; }
function fetch_result($id) { return _fetch_result($id); }
function update_result($result, $id) { return _update_result($result, $id); }
function insert_result($result) { return _insert_result($result); }
protected function _fetch_result($id) {
if (!$this->valid) { return NULL; }
$result = new Result($id, $this->table);
if (!$result) { return NULL; }
else { return $result; }
}
protected function _update_result($result, $id) {
if ($result->get_table() != $this->table) { return NULL; }
$query = "UPDATE `".$this->table."` SET ";
$names = $result->get_result_names();
foreach ($names as $index => $name) {
if ($name != "id") {
$value = $result->get_result_value($name);
$query = $query ."`".$name."`=";
if (is_string($value)) { $query = $query."'".$value."'"; }
else { $query = $query.$value; }
if ($index < count($names)) { $query = $query.", "; }
}
}
$query = $query . " WHERE `id`=".$id." LIMIT 1";
mysafe_unlock();
if (!$this->conn = mysafe_connect())
{ mysafe_lock(); return mysql_error(); }
if (!$ret = mysafe_query($query, $this->conn)) { mysafe_close($this->conn); mysafe_lock(); return mysql_error()."[[query]]"; }
else { mysafe_close($this->conn); mysafe_lock(); return $ret; }
}
protected function _insert_result($result) {
if ($result->get_table() != $this->table) { return NULL; }
$query = "INSERT INTO `".$this->table."` (";
$names = $result->get_result_names();
foreach ($names as $index => $name) {
if ($name != "id") {
$query = $query."`".$name."`";
if ($index < count($names)) { $query = $query.", "; }
}
}
$query = $query." ) VALUES( ";
foreach ($names as $index => $name) {
if ($name != "id") {
$value = $result->get_result_value($name);
if (is_string($value)) { $query = $query."'".$value."'"; }
else { $query = $query.$value; }
if ($index < count($names)) { $query = $query . ", "; }
}
}
$query = $query . " )";
mysafe_unlock();
if (!$this->conn = mysafe_connect())
{ mysafe_lock(); return mysql_error(); }
if (!$ret = mysafe_query($query, $this->conn)) { mysafe_close($this->conn); mysafe_lock(); return mysql_error()."[[$query]]"; }
else { mysafe_close($this->conn); mysafe_lock(); return $ret; }
}
protected function get_num_rows() { return mysql_num_rows($this->result); }
protected function get_row_at($row) {
if (mysql_data_seek($this->result, $row)) { return mysql_fetch_assoc($this->result); } else return NULL;
}
protected function get_next_row() { return mysql_fetch_assoc($this->result); }
protected function get_first_row() {
if (mysql_data_seek($this->result, 0) { return mysql_fetch_assoc($this->result); } else return NULL;
}
protected function get_last_row() {
if (mysql_data_seek($this->result, mysql_num_rows($this->result) - 1)) { return mysql_fetch_assoc($this->result); } else return NULL;
}
protected function get_result_value() {}
protected function get_result_names() {}
protected function set_result_value() {}

protected $count;
protected $page;
protected $start;
protected $end;
protected $order;
}

?>


:cool: