I've been working on learning OOP and classes, and I wanted a critique on a simple project I'm writing.
I wrote a couple of classes to make it easier for me to generate a table using MySQL and PDO. It's still being worked on, but I wanted to make sure that I haven't "Broken" anything.
My main question is I'm wondering if what I wrote is still considered "secure", mostly from SQL injection.
index.php:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Database Class</title>
</head>
<body>
<?php
include 'class.MySQL.php';
include 'class.TableBuilder.php';
//Check to make sure a valid connection has been made
//If so, instantiate the object and login to the database
$db = (new MySQLDatabase_Object)->check_login();
//Define the columns headings
//Can be empty, but shouldn't be
//Example:
//"First Name"
//"Last Name"
$columns = array(
'First Name',
'Last Name',
'Street Address'
);
//Build the 'SELECT' query fields
//Cannot be empty
//Example:
//"leads.fname" => "fname means"
//"leads.fname" => "fname"
$fields = array(
'leads.fname' => 'fname',
'leads.lname' => 'lname',
'leads.addr_street' => 'addr_street'
);
//Builds the 'FROM' query values
//This will be a single table name
//Cannot be empty
//Example:
//"leads"
$tables = array('leads');
//Builds the 'WHERE' query
//Can only use the JOIN query or the WHERE query, not both
//Can be empty
//Examples:
//"WHERE leads.fname LIKE '%Walt%'"
//"WHERE leads.fname = 'Walter'"
$where = array(
);
//Builds the JOIN query
//Can only use the JOIN query or the WHERE query, not both
//Can be empty
//Examples:
//"INNER JOIN appointments" => "leads.id = appointments.lead"
//"INNER JOIN leads_notes" => "leads.id = leads_notes.id_lead"
$join = array(
);
//Builds the AND/OR/NOT query
//Can be empty
//Examples:
//"AND leads.assigned = 1"
//"OR leads.assigned != 0"
//"NOT leads.assigned = 0"
$and = array(
);
//Sets the 'ORDER BY' clause
//Can be empty
//Example:
//"leads.lname ASC"
//"leads.fname DESC"
$order = array(
);
//Build and return the query
$query = MySQLDatabase_Object::query_builder_select($fields, $tables, $where, $join, $and, $order);
//Gather the result set from the query and
//place them in a nested array
$result_set = MySQLDatabase_Object::results($fields, $db, $query);
//Build the table, based on the result set and columns
//and print the table to the screen
$table = new MySQLTable;
echo $table->buildTable($columns, $result_set);
?>
</body>
</html>
class.MySQL.php:
<?php
class MySQLDatabase_Object {
//Create the database connection and attempt to login to the database
private function login() {
$host = "localhost"; //Host Name
$port = '3306'; //Default MySQL Port
$dbname = "xxxxxx"; //Database Name
$db_username = "xxxxxx"; //MySQL Username
$db_password = "xxxxxx"; //MySQL Password
$dsn = "mysql:host=$host;port=$port;dbname=$dbname"; //Data Source Name = Mysql
$db = new PDO($dsn, $db_username, $db_password); //Connect to DB
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $db;
}
//Public-facing login method to log into the database and return the $db PDO
public function check_login() {
$db = $this->login();
return $db;
}
static function query_builder_select($fields, $tables, $where, $join, $and, $order) {
//Process the SELECT fields
$select_fields = self::check_fields($fields);
//Process the FROM field
$tables = self::check_table($tables);
//Processes the JOIN or WHERE fields
if (!empty($where) && !empty($join)) {
die("You can only use one of the JOIN or WHERE clauses. Not both.");
} elseif (!empty($where)) {
$where = self::check_where($where);
} elseif (!empty($join)) {
$where = self::check_join($join);
} else {
$where = null;
}
//Process the AND/OR/NOT fields
$and = self::check_and($and);
//Process the ORDER BY fields
$order = self::check_order($order);
//Build the SELECT query
$query = "SELECT $select_fields ";
$query .= "FROM $tables";
if (!is_null($where)) {
$query .= " $where";
}
if (!is_null($and)) {
$query .= " $and";
}
if (!is_null($order)) {
$query .= " ORDER BY $order";
}
echo $query;
return $query;
}
private static function check_fields($fields) {
//Purpose: Gathers all the values from the $fields array
//and formats them correctly to generate a correct "SELECT" statement
//Check for an empty array
if (empty($fields)) {
die("No query fields selected");
}
//
$select_fields = '';
foreach ($fields AS $key => $value) {
$select_fields .= "$key AS $value,";
}
//Remove the trailing comma from the last element in the array
$select_fields = trim($select_fields, ',');
return $select_fields;
}
private static function check_table($tables) {
//Get the table array elements and seperate them with a comma
if (!empty($tables)) {
$tables = implode(',', $tables);
$tables = trim($tables, ',');
} else {
die('No Tables selected');
}
return $tables;
}
private static function check_where($where) {
//Get the WHERE array elements and seperate them with a comma
if (!empty($where)) {
$where = implode(',', $where);
$where = trim($where, ',');
} else {
$where = null;
}
return $where;
}
private static function check_join($join) {
$join_options = '';
if (!empty($join)) {
foreach ($join AS $key => $value) {
$join_options .= " $key ON $value ";
}
} else {
$join_options = null;
}
return $join_options;
}
private static function check_and($and) {
//Get the WHERE array elements and seperate them with a comma
if (!empty($and)) {
$and = implode(' ', $and);
$and = trim($and, ' ');
} else {
$and = null;
}
return $and;
}
private static function check_order($order) {
//Get the order array elements and seperate them with a comma
if (!empty($order)) {
$order = implode(',', $order);
$order = trim($order, ',');
} else {
$order = null;
}
return $order;
}
static function results($fields, $db, $query) {
//Run the prepared query
$stmt = $db->prepare($query);
$stmt->execute();
$results = array();
$field_array = array();
foreach ($stmt->fetchAll(PDO::FETCH_OBJ) as $row) {
//Build the nested arrays
foreach ($fields AS $key => $value) {
$$value = $row->$value;
array_push($field_array, $$value);
}
//Add the nested arrays to the main array ($results)
array_push($results, $field_array);
$field_array = array();
}
return $results;
}
}
class.TableBuilder.php:
<?php
class MySQLTable {
public function buildTable($columns, $result_set) {
//Create an empty table
$table = '';
$table .= '<table border="1">';
//Build the column structure, passed in from the $columns array
$table .= "<tr>";
foreach ($columns as $column) {
$table .= "<td>$column</td>";
}
$table .= "</tr>";
//Build the rows from the $result_set array
foreach ($result_set AS $array) {
$table .= "<tr>";
//Pass each nested array to the table as a single row
//per nested array
foreach ($array AS $table_cell) {
$table .= "<td>$table_cell</td>";
}
//Placeholder for adding additional columns (usually button columns)
// $table .= "<td><button type='button'>Test</button></td>";
$table .= "</tr>";
}
//Complete the table
$table .= "</table>";
return $table;
}
}
In order to get this to work, you need to modify class.MySQL.php with your database information.
You can modify $fields and $columns in index.php to see how it works. In theory, you should be able to name your columns in the '$columns' array, your MySQL SELECT fields in the $fields array, and your table name in $tables.
If you need more info, I'd be glad to help.
I'm aware that there is only simple 'WHERE' and 'JOIN' clause handling. I will be working on this next.
Thanks for any critique!
Related
I am trying to learn object oriented programming.
The problem what I have is how to add link under mysqli_query() inside the class.
In procedural style I just create a $variable with connection details and then using it inside the mysqli_query($variable, $sql) etc.
In my class I have function connect() which will connect to database and return true but Haw can I use it inside my mysqli_query() please? please see the code here:
<?php
class DB {
protected $db_name = 'OOP_forum';
protected $db_user = 'Marcel';
protected $db_pass = *****;
protected $db_host = 'localhost';
public function connect() {
$connection = mysqli_connect($this->db_host, $this->db_user, $this->db_pass);
mysqli_select_db($connection, $this->db_name);
return true;
}
public function processRowSet($rowSet, $singleRow = false) {
$resultArray = array();
while($row = mysqli_fetch_assoc($rowSet)) {
arraypush($resultArray, $row);
}
if($singleRow==true) {
return $resultArray[0];
}else {
return $resultArray; }
}
public function select ($table, $where, $column = '*') {
$sql = "SELECT $column FROM $table WHERE $where";
$result = mysqli_query($sql);
if(mysqli_num_row($result) == 1 ){
return $this->processRowSet($result, true);
} else
{ return $this->processsRowSet($result);
}
}
public function update ($data, $table, $where) {
foreach ($data as $column->$value) {
$sql = "UPDATE $table SET $column = $value WHERE $where";
mysqli_query($sql) or die(mysqli_error());
}
return true;
}
public function delete ($table, $column, $where) {
$sql = "DELETE FROM $table WHERE $column = $where";
if (query($sql)=== TRUE) {
echo "Record Deleted sucessfully";
}else {
echo "Error deleting record: " . $connection->error;
}
}
public function insert($data, $table) {
$columns = "";
$values = "";
foreach ($data as $column->$value) {
$columns .= ($columns == "") ? "": ", " ;
$columns .= $column;
$values .= ($values == "") ? "" : ", ";
$values .= $value;
}
$sql = "insert into $table ($columns) values ($values)";
mysqli_query($sql) or die(mysqli_error());
return mysqli_insert_id();
}
}
?>
Before trying to learn OOP programming you have to learn basic OOP syntax.
In order to do so forget for a while about creating your own classes and learn how to use already made ones. So, first of all learn how to use mysqli. Which is already a class.
Better yet, learn PDO instead, as, unlike mysqli, it's already a ready to use database access class, with it you don't need functions like processRowSet, for example.
the problem is my function insert inserts my record in two rows.
this is my code to connect to database in a file named :
connect.php
<?php
try{
$db = new PDO("mysql:host=localhost;dbname=NPD" , "root" , "");
echo "connected";
}
catch(Exception $e){
echo $e->getMessage();
}
this is my database class in a file
database.php
<?php
require 'connect.php';
class DB {
public function insertInto($tableName , $info){
global $db;
foreach ($info as $coloumnName => $coloumnValue) {
$stmt = $db->prepare("INSERT INTO $tableName ($coloumnName) VALUES ('$coloumnValue') ");
$stmt->execute();
}
}
}
$da = new DB;
$da->insertInto('tableOne',array('name' => 'lolo' , 'deg' => '100'));
the result in the database is :
tableOne
how can to make the insert function inserts my record in one row.
note : i want to insert any number of columns and values.
try to do something like this:
$arr = array('name' => 'lolo' , 'deg' => '100');
$columns=array_keys($arr);
$values=array_values($arr);
$str="INSERT INTO $tableName (".implode(',',$columns).") VALUES ('" . implode("', '", $values) . "' )";
echo $str;//your sql
// $stmt = $db->prepare($str);
// $stmt->execute();//uncomment to execute
Like this but there are some concerns ( also I haven't tested this )
class DB {
protected $_conn;
public function __construct( $user, $pass, $database='NPD', $host='localhost' ){
try{
$this->_conn = new PDO("mysql:host={$host};dbname={$database}" , $user , $pass);
echo "connected";
}catch(Exception $e){
echo $e->getMessage();
}
}
public function insertInto($tableName , $info){
$sql = 'INSERT INTO $tableName (';
$sql .= '`'implode('`,`', array_keys($info[0])).'`';
$sql .= ')VALUES';
foreach ($info as $index => $row) {
$sql .= '(';
foreach( $row as $column => $value){
$sql .= ':'.$column.$index.',';
$params[':'.$column.$index] = $value;
}
$sql = rtrim($sql, ',');
$sql .= '),';
}
$sql = rtrim($sql, ',');
$stmt = $this->_conn->prepare($sql);
$stmt->execute($params);
}
}
}
$da = new DB('root', '');
$da->insertInto('tableOne',array( array('name' => 'lolo' , 'deg' => '100') ) );
First of all you loose any sql injection protection on the column names. If you can manage the placeholders on the values, then that is ok, but without using them there you loose protection on that as well. This can be solved by using the db schema itself, via Show columns but that gets a wee bit complex.
https://dev.mysql.com/doc/refman/5.7/en/show-columns.html
Second, your input array structure is all wrong, it needs to be array(0=>array(...), 1=>array(...)) instead of just array(...)
Third I would make this class a "Singleton" but that's just me
http://coderoncode.com/design-patterns/programming/php/development/2014/01/27/design-patterns-php-singletons.html
Forth, if you just want to do a single row at a time you can change this method
public function insertInto($tableName , $info){
$sql = 'INSERT INTO $tableName (';
$sql .= '`'implode('`,`', array_keys($info)).'`';
$sql .= ')VALUES(';
$params = array();
foreach( $info as $column => $value){
$sql .= ':'.$column.$index.',';
$params[':'.$column.$index] = $value;
}
$sql = rtrim($sql, ',');
$sql .= ')';
$stmt = $this->_conn->prepare($sql);
$stmt->execute($params);
}
And use the current input array structure you have.
This Is how i coded my own insert function
public function insertRecord($table,$records){
//A variable to store all the placeholders for my PDO INSERT values.
$placeholder = '';
for ($i = 0; $i < sizeof($records); $i++){
$placeholder[$i] = '?';
}
//A FOR-LOOP to loop through the records in the $record array
$placeholder = implode(',', $placeholder);
//Imploding ',' in between the placeholders
$sql = "INSERT INTO ".$table." VALUES ("{$placeholder}")";
$query = $this->dbh->prepare($sql);
$query->execute($records);
}
It Might not be the best..worked for me though.
As some other answers/comments have stated, there are quite a few critiques one could make about this overall process. However, in the interests of simply answering the question, you may want to just build the statement by looping through the columns, then looping through the values, then executing the finished statement (code below is just an example and hasn't been tested):
require 'connect.php';
class DB {
public function insertInto($tableName , $info){
global $db;
$query = "INSERT INTO $tableName (";
$columns = array_keys($info);
// build the columns in the statement
$length = count($columns);
foreach($columns as $index => $column) {
$query .= "$column";
if ($index+1 < $length) {
$query .= ','
}
}
$query .= ") VALUES ("
// build the values in the statement
$i = 1;
$length = count($info);
foreach($info as $value) {
$query .= "'$value'"
if ($i < $length) {
$query .= ","
}
$i++;
}
$query .= ")"
$stmt = $db->prepare($query);
$stmt->execute();
}
}
$da = new DB;
$da->insertInto('tableOne',array('name' => 'lolo' , 'deg' => '100'));
I have a HTML form which has more than 25 entries.
I know how to insert normal form data into MySQL database using PHP PDO. But I just want to know if there is any alternative way in which I can store the form entries to an array and insert the data into database using the array.
Because writing an insert statement for more than 25 columns is cumbersome.
You could always use a PDO wrapper class, I use the class below to handle most of my PDO queries:
class DB {
protected
// Return from mysql statement
$data = array(),
// Used for checking whether something was added to the JSON object and remove it if the table column doens't exist
$table_cols = array(),
// Storing the table name we are working with
$table = '';
protected static
// PDO connection to the DB
$_conn = null,
// The DB credentials retrieved from the ini file
$_credentials = array ();
private
$_id = -1,
$_keys = array(),
$_values = array(),
$_last_insert_id = -1,
$_results = array();
//
// PUBLIC FUNCTIONS
//
public function __construct () {
if (self::$_conn === null) {
self::setCredentials();
try {
self::$_conn = new \PDO("mysql:host=" . self::$_credentials['host'] . ";dbname=" . self::$_credentials['dbname'] , self::$_credentials['username'], self::$_credentials['password']);
} catch (\PDOException $e) {
DebugLog::instance('DB')->error($e, 'db_connection');
}
}
}
public function insert ($data) {
$data = $this->checkCols($data);
// Allows us to quickly clone data by removing the id and inserting as a new record
if (isset($data['id'])) {
unset($data['id']);
}
$this->data = $data;
$this->setDataBinding();
$sql = "INSERT INTO `" . self::$_credentials['dbname'] . "`.`{$this->table}` (`" . implode('`, `', $this->_keys) . "`) VALUES (:" . implode(', :', $this->_keys) . ");";
return $this->prepareAndExecute($sql);
}
public function update ($data) {
$data = $this->checkCols($data);
if (!isset($data['id'])) {
// Houston we have a problem, there needs to be an id to update a record
DebugLog::instance('DB')->error("No ID set for Update: " . implode(', ', array_keys($data)), 'db_id_' . $this->table);
} else {
// We need to unset the id because it shouldn't be in the data binding
// But we still hold onto it for the where clause
$id = $data['id'];
unset($data['id']);
$this->data = $data;
$this->setDataBinding();
$sql = "UPDATE `" . self::$_credentials['dbname'] . "`.`{$this->table}` SET ";
$query_string = "";
foreach ($this->_keys as $i => $key) {
$query_string .= "`{$key}` = :{$key}, ";
}
$query_string = trim($query_string);
if (substr($query_string, -1) === ',') {
$query_string = substr($query_string, 0, -1);
}
$sql .= $query_string . " WHERE `id` = '{$id}'";
return $this->prepareAndExecute($sql);
}
return false;
}
public function remove ($id) {
$this->rawQuery("DELETE FROM `{$this->table}` WHERE `id` = '{$id}';");
}
public function rawQuery ($sql) {
try {
$pdo = self::$_conn->query($sql);
$pdo->setFetchMode(\PDO::FETCH_ASSOC);
} catch (\PDOException $e) {
DebugLog::instance('DB')->error($e, 'db_query_' . $this->table);
return array();
}
return $pdo->fetchAll();
}
//
// GETTERS
//
public function getColumns () {
return $this->table_cols;
}
public function getLastInsertID () {
return $this->_last_insert_id;
}
public function getRecord ($id) {
$this->_id = $id;
$response = $this->rawQuery("SELECT * FROM `{$this->table}` WHERE `id` = '{$id}'");
$this->_results = $response[0];
}
public function getResults () {
return $this->_results;
}
public function close () {
$this->setDefaults();
}
//
// PROTECTED FUNCTIONS
//
protected function initColumns () {
$sql = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '" . self::$_credentials['dbname'] . "' AND TABLE_NAME = '{$this->table}';";
$response = $this->rawQuery($sql);
if (!empty($response)) {
return $this->parseColumns($response);
}
return array();
}
//
// PRIVATE FUNCTIONS
//
private function setDataBinding () {
$this->_keys = array_keys($this->data);
foreach ($this->data as $k => $v) {
$this->_values[':' . $k] = $v;
}
}
private function prepareAndExecute ($sql) {
try {
$q = self::$_conn->prepare($sql);
$q->setFetchMode(\PDO::FETCH_ASSOC);
if ($q->execute($this->_values)) {
while ($r = $q->fetch()) {
$this->_results[] = $r;
}
$this->_last_insert_id = self::$_conn->lastInsertId();
return true;
} else {
DebugLog::instance('DB')->error('Failed to execute', 'db_' . $this->table);
}
} catch (\PDOException $e) {
DebugLog::instance('DB')->error($e, 'db_' . $this->table);
}
return false;
}
private function checkCols ($array) {
foreach ($array as $col => $val) {
if (!in_array($col, $this->table_cols)) {
unset($array[$col]);
}
}
return $array;
}
private static function setCredentials () {
// I actually use a config file here, instead of hard coding
self::$_credentials = array(
'host' => '',
'dbname' => '',
'username' => '',
'password' => ''
);
}
private function parseColumns ($cols) {
$array = array();
foreach ($cols as $index => $col_array) {
$array[] = $col_array['COLUMN_NAME'];
}
return $array;
}
private function setDefaults () {
$this->data = array();
$this->table_cols = array();
$this->table = '';
self::$_conn = null;
$this->_keys = array();
$this->_values = array();
$this->_last_insert_id = -1;
$this->_results = array();
}
}
Then for each table, create a class that extends the class above. For example, lets say we have a users table:
class UsersTable extends DB {
public function __construct () {
// Parent constructor creates the DB connection
parent::__construct();
// Now let's set the desired table based on this class
$this->table = "users";
// Set the table columns, for mysql column validation
$this->table_cols = $this->initColumns();
}
}
Usage is than as simple as:
$table = new UsersTable();
$table->insert($record);
As long as your array has the 25 values in the same order as the table you can use unnamed parameters and lazy binding See PDO info
$sql ="INSERT INTO table_name VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,)";
$stmt = $dbh->prepare($sql);
$stmt->execute($array);
Here is my array :
protected static $db_fields = array('id', 'username', 'password');
Here is how I use it for:
protected function attributes(){
$attributes = array();
foreach(static::$db_fields as $field){
$attributes[$field] = $this->$field;
}
return $attributes;
}
Here is how I use attributes :
protected function create(){
global $database;
$attributes = $this->sanitized_attributes();
$sql = "INSERT INTO " . static::$table_name . " (";
$sql .= join(", ", array_keys($attributes));
$sql .= ") VALUES ('";
$sql .= join("', '", array_values($attributes));
$sql .= "')";
if($database->query($sql)){
$this->id = $database->inserted_id();
return TRUE;
}else{
return FALSE;
}
}
All I need to do is to generate that db_fields array from the database directly not assigning it manually like what I did. I played around with 'SHOW COLUMNS FROM' table name, but without any luck.
Show columns :
function attributes(){
global $database;
$attributes = array();
$sql = "SHOW COLUMNS FROM " . static::$table_name;
$result = $database->query($sql);
$db_fields = mysql_fetch_assoc($result);
for($i = 0; $i < mysql_num_rows($result); $i++){
while ($db_fields = mysql_fetch_assoc($result)) {
$attributes[] = $db_fields['Field'];
}
}
return $attributes;
}
My final approach should be an array like:
$db_fields = ('column1_name', 'column2_name', 'column3_name')
The result of my current "SHOW COLUMNS" play around is that it makes the value of username: username, password: password ... just as the column's name.
I believe it's how I assign these columns names to my array is the problem. So what is the right query to make such an array?
Finall I solved it:
protected static $db_fields;
function __construct(){
self::generate_attributes();
}
protected static function generate_attributes(){
$sql = "SHOW COLUMNS FROM admins";
$result = mysql_query($sql);
$rows = mysql_fetch_assoc($result);
for($i = 0; $i < mysql_num_rows($result); $i++){
while ($rows = mysql_fetch_assoc($result)) {
self::$db_fields[] = $rows['Field'];
}
}
return self::$db_fields;
}
protected function attributes(){
$attributes = array();
foreach(static::$db_fields as $field){
$attributes[$field] = $this->$field;
}
return $attributes;
}
Thank you all for trying to help.
How about trying
SELECT `column_name` FROM `information_schema`.COLUMNS WHERE TABLE_NAME = 'yourtable';
Your db user wil require read access on the information_schema.
If required, you can also use GROUP_CONCAT to create a comma separated string.
SELECT GROUP_CONCAT(c.column_name) FROM `information_schema`.COLUMNS c WHERE TABLE_NAME = 'yourtable';
$query = "SELECT * from myTable LIMIT 1";
if ($result = mysqli_query($link, $query)) {
$finfo = mysqli_fetch_fields($result);
foreach ($finfo as $val) {
print_r($val);
}
mysqli_free_result($result);
}
Try This:
function attributes(){
global $database;
$attributes = array();
$sql = "SELECT column1_name,column2_name,column3_name FROM " . static::$table_name;//your columns
$result = $database->query($sql);
$db_fields = array('column1_name', 'column2_name', 'column3_name') ;
$i=0;
if(mysql_num_rows($result)){
while ($rows = mysql_fetch_row($result)) {
for($j=0;$j<count($db_fields);$j++)
{
$attributes[$i][$db_fields[$j]] = $rows[$j] ;
}
$i++;
}
}
return $attributes;
}
Try these
use your table name and schema to get all details regarding to columns.
SELECT `column_name` FROM `information_schema`.COLUMNS WHERE TABLE_NAME = 'table_name' AND TABLE_SCHEMA = 'database_name'
you can use * instead of column_name
check inaformation_schema table it has lot much to know
I have 3 files:
DB.class.php - which handles all the databases.
Site.class.php - contains a function to return the latest entries in a database.
index.php - trying to print the array passed.
I am trying to pass an array into index.php from Site.class.php which is using a function from DB.class.php to put the mysql results into an associative array.
index.php:
<?php
// index.php
include 'classes/Site.class.php';
$site = new Site();
print_r($site->latestBookmarks());
?>
Site.class.php:
<?php
// Site.class.php
require_once 'DB.class.php';
class Site {
function latestBookmarks() {
$result = mysql_query("SELECT url, title FROM site ORDER BY id DESC");
$db = new DB();
return $db->processRowSet($result);
}
}
?>
DB.class.php:
<?php
// DB.class.php
class DB {
protected $db_name = "project";
protected $db_user = "root";
protected $db_pass = "root";
protected $db_host = "localhost";
// Open up a connection to the database.
public function connect() {
$connection = mysql_connect($this->db_host, $this->db_user, $this->db_pass);
mysql_select_db($this->db_name);
return true;
}
// Takes a MySQL row and returns an associative array where the keys in the array are the column names in the row set.
public function processRowSet($rowSet, $singleRow=false) {
$resultArray = array();
while ($row = mysql_fetch_assoc($rowSet)) {
array_push($resultArray, $row);
}
if ($singleRow === true)
return $resultArray[0];
return $resultArray;
}
// Select rows from the database.
public function select($table, $where) {
$sql = "SELECT * FROM $table WHERE $where";
$result = mysql_query($sql);
if (mysql_num_rows($result) == 1)
return $this->processRowSet($result, true);
return $this->processRowSet($result);
}
// Update a current row in the database.
public function update($data, $table, $where) {
foreach ($data as $column => $value) {
$sql = "UPDATE $table SET $column = $value WHERE $where";
mysql_query($sql) or die(mysql_error());
}
return true;
}
// Insert a new row into the database.
public function insert($data, $table) {
$columns = "";
$values = "";
foreach ($data as $column => $value) {
$columns .= ($columns == "") ? "" : ", ";
$columns .= $column;
$values .= ($values == "") ? "" : ", ";
$values .= $value;
}
$sql = "INSERT INTO $table ($columns) VALUES ($values)";
mysql_query($sql) or die(mysql_error());
return mysql_insert_id();
}
}
?>
A few problems I noticed:
You run a query in function latestBookmarks before you connect to the db;
In your function connect you connect to a database, but the result is discarded immediately, $connection is lost as soon as the function finishes.
You have no connection to the database when you run this line:
$result = mysql_query("SELECT url, title FROM site ORDER BY id DESC");
You will need to adjust your code to send the query string to the DB instance for processing. You can add a method to DB to execute mysql_query, and pass the query in like from Site:: latestBookmarks() like this:
$db = new DB();
$db->executeQuery("SELECT url, title FROM site ORDER BY id DESC");
return $db->processRowSet();