Jump to content

[SOLVED] PHP5 Method Chaning with my SQL Class


Demonic

Recommended Posts

<?php
/*
/******************************
|@ Version 2
|@ Copyrighted Nevux Ability Boards 2007
|@ All rights reserved
|@ Author: Lamonte Harris
\******************************
*/

//include mysql driver class
require_once("./sources/classes/drivers/mysql.php");
$db = new MySQL;
$db->con("localhost","root","p4ss")->db("nevux")->push_err();
?>

 

Is my basic class, when outputted push_error doesn't output nothing heres my main class.

 

<?php
/*
/******************************
|@ Version 2
|@ Copyrighted Nevux Ability Boards 2007
|@ All rights reserved
|@ Author: Lamonte Harris
\******************************
*/

//MySQL CLass
class MySQL
{	
private $error_msg;
//mysql connection variables
private $sql_pass;
private $sql_user;
private $sql_host;
private $sql_database;

//query variable
private $sql_query;
//returns an array of the sql last fetched
private $sql_fetch;
//set query
public function set_query($parameter)
{
	$parameter = mysql_real_escape_string($parameter);
	$this->sql_query = $parameter;
	return $this;
}

//query
public function query()
{
	$this->sql_fetch = mysql_query($this->sql_query);
	return $this->sql_fetch();
}

//connection
public function con($h,$u,$p)
{
	$this->sql_user = $u;
	$this->sql_pass = $p;
	$this->sql_host = $h;
	if(!@mysql_connect($this->sql_host,$this->sql_user,$this->sql_pass))
	{
		$this->error_msg .= mysql_error() . ", ";
	}
	return $this;
}

//select db
public function db($d)
{
	$this->sql_database = $d;
	if(!@mysql_select_db($this->$sql_database))
	{
		$this->error_msg .= mysql_error() . ", ";
	}
	return $this;
}
public function push_err()
{
	if(strlen($this->error_msg) > 0)
	{
		print $this->error_msg;
	}
	else
	{
		print "clean";
	}
}
}
?>

 

Connects to db successfully.

Link to comment
Share on other sites

ignore .....

 

do you get any return value?

 

when outputted push_error doesn't output nothing heres my main class.

 

If I added a else on the sql connection and select db's it would echo but in the push_err it doesn't output nothing..

 

<?php
error_reporting(E_ALL);
/*
/******************************
|@ Version 2
|@ Copyrighted Nevux Ability Boards 2006-2007
|@ All rights reserved
|@ Author: Lamonte Harris
\******************************
*/

//MySQL CLass
class MySQL
{	
private $error_msg;
//mysql connection variables
private $sql_pass;
private $sql_user;
private $sql_host;
private $sql_database;

//query variable
private $sql_query;
//returns an array of the sql last fetched
private $sql_fetch;
//set query
public function set_query($parameter)
{
	$parameter = mysql_real_escape_string($parameter);
	$this->sql_query = $parameter;
	return $this;
}

//query
public function query()
{
	$this->sql_fetch = mysql_query($this->sql_query);
	return $this->sql_fetch();
}

//connection
public function con($h,$u,$p)
{
	echo "con<br />";
	$this->sql_user = $u;
	$this->sql_pass = $p;
	$this->sql_host = $h;
	if(!@mysql_connect($this->sql_host,$this->sql_user,$this->sql_pass))
	{
		$this->error_msg .= mysql_error() . ", ";
	}
	return $this;
}

//select db
public function db($d)
{
	echo "db";
	$this->sql_database = $d;
	if(!@mysql_select_db($this->$sql_database))
	{
		$this->error_msg .= mysql_error() . ", ";
	}
	return $this;
}
public function push_err()
{
	echo "clean";
	if(strlen($this->error_msg) > 0)
	{
		print $this->error_msg;
	}
	else
	{
		print "clean";
	}
}
}
?>

 

Updated that function echos nothing.

 

output:

 

con

db

Link to comment
Share on other sites

I'm interested to bump this thread and find out the real reason for using chaining methods.

my impression of chaining was that really you should passing over to different classes in the chain, not the same class. Otherwise you might as well do

 

$class = new Object();

$class->func1();

$class->func2();

$class->func3();

 

Chaining in this instance only means you can do

$class = new Object();

$class->func1()->func2()->func3();

 

Link to comment
Share on other sites

I'm interested to bump this thread and find out the real reason for using chaining methods.

my impression of chaining was that really you should passing over to different classes in the chain, not the same class. Otherwise you might as well do

 

$class = new Object();

$class->func1();

$class->func2();

$class->func3();

 

Chaining in this instance only means you can do

$class = new Object();

$class->func1()->func2()->func3();

 

 

less lines cleaner look, and thats my choice, you really don't have to do it.

Link to comment
Share on other sites

True,

 

I was just mooching over the possible advantage that one might gain from chaining. It also occurs to me there potential for a greater loss here, because those functions can ONLY ever return $this (or a reference to another object), so you're negating any other return values. Fine of course if you don't need them ;)

Link to comment
Share on other sites

You don't necessarily have to return $this.

 

You could imagine having a class called Database_MySQL. The method Database_MySQL::query() would return an object of DatabaseResult_MySQL which could implement methods like get_num_rows() and fetch_assoc().

 

In that way you could do:

echo 'Users:';
while($db->query("SELECT id, username FROM users")->fetch_assoc() as $user)
{
echo "<br /><a href='/profiles/{$user['id']}'>{$user['username']}</a>";
}

Link to comment
Share on other sites

You don't necessarily have to return $this.

 

You could imagine having a class called Database_MySQL. The method Database_MySQL::query() would return an object of DatabaseResult_MySQL which could implement methods like get_num_rows() and fetch_assoc().

 

In that way you could do:

echo 'Users:';
while($db->query("SELECT id, username FROM users")->fetch_assoc() as $user)
{
echo "<br /><a href='/profiles/{$user['id']}'>{$user['username']}</a>";
}

that how basically my first post is set up..

Link to comment
Share on other sites

Hmm, actually, it wouldn't be a good idea to use the above snippet I posted in that way since if there are a million users then the query will be run a million times. Still, it isn't like you did though.

 

Also, it's done wrong... it should've been

$user = $db->query("SELECT id, username FROM users")->fetch_assoc()

not

$db->query("SELECT id, username FROM users")->fetch_assoc() as $user

Link to comment
Share on other sites

Hmm, actually, it wouldn't be a good idea to use the above snippet I posted in that way since if there are a million users then the query will be run a million times. Still, it isn't like you did though.

 

Also, it's done wrong... it should've been

$user = $db->query("SELECT id, username FROM users")->fetch_assoc()

not

$db->query("SELECT id, username FROM users")->fetch_assoc() as $user

I seen..(your thinking foreach())

Link to comment
Share on other sites

This is what I mean:

 

<?php
/**
* The timer class is used for finding out how long time
* some code takes to execute.
*
* @author Daniel Egeberg
*/
class Timer
{
/**
 * Holds the start time
 *
 * @access private
 * @var float
 */
private $start_time;

/**
 * The constructor starts the timer.
 *
 * @magic
 * @access public
 */
public function __construct()
{
	$this->start_time = microtime();
}

/**
 * Gets the time since the timer started.
 *
 * @access public
 * @return float
 */
public function get_time()
{
	$start_time	= explode(' ', $this->start_time);
	$stop_time	= explode(' ', microtime());

	$start_time	= $start_time[0] + $start_time[1];
	$stop_time	= $stop_time[0] + $stop_time[1];

	return $stop_time - $start_time;
}
}

/**
* Main database class. Holds common database methods and defines
* functions which must be implemented in child classes. This class
* is abstract and can therefore not be instantiated.
*
* @abstract
* @author Daniel Egeberg
*/
abstract class Database
{
/**
 * Hostname
 *
 * @access protected
 * @var string
 */
protected $host;

/**
 * Username
 *
 * @access protected
 * @var string
 */
protected $username;

/**
 * Password
 *
 * @access protected
 * @var string
 */
protected $password;

/**
 * Database
 *
 * @access protected
 * @var database
 */
protected $database;

/**
 * Is the connection persistent?
 *
 * @access protected
 * @var boolean
 */
protected $persistent;

/**
 * The link to the database.
 *
 * @access public
 * @var mixed
 */
protected $db_link;

/**
 * The result of the last query
 *
 * @access protected
 * @var DatabaseResult
 */
protected $last_result;

/**
 * The constructor sets some connection information and then connects.
 *
 * @magic
 * @access public
 * @param string $host
 * @param string $username
 * @param string $password
 * @param string $database
 * @param boolean $persistent
 */
public function __construct($host, $username, $password, $database, $persistent = false)
{
	$this->host		= (string) $host;
	$this->username	= (string) $username;
	$this->password = (string) $password;
	$this->database = (string) $database;
	$this->persistent = (boolean) $persistent;

	$this->connect();
}

/**
 * The factory is used to get a specific children of Database.
 * 
 * $type could e.g. be MySQL or SQLite
 *
 * @static
 * @param string $type
 * @param string $host
 * @param string $username
 * @param string $password
 * @param boolean $persistent
 * @return Database
 */
public static function factory($type, $host, $username, $password, $persistent = false)
{
	$class_name = "Database_{$type}";
	return new $class_name($host, $username, $password, $persistent);
}

/**
 * The insert method simplifies insertion of data to the database. If $generate_only is set
 * to true, then it will return the generated SQL instead of executing it. Values will by
 * default be escaped unless $escape_data is set to false.
 * 
 * $data requires the key to be the field name and the value to be the wanted value. E.g.:
 * 
 * <pre>
 * $data = array(
 * 		'username' => 'john',
 * 		'password' => 'qwerty',
 * 	);
 * </pre>
 *
 * @access public
 * @param string $table
 * @param array $data
 * @param boolean $escape_data
 * @param boolean $generate_only
 * @return string|DatabaseResult
 */
public function insert($table, array $data = array(), $escape_data = true, $generate_only = false)
{
	if(count($data) < 1) return false;

	$field_names = $values = array();
	foreach($data as $field_name => $value)
	{
		$field_names[]	= $field_name;
		$values[]		= "'".($escape_data ? $this->escape_string($value) : $value)."'";
	}

	$sql = "INSERT INTO {$table} (".join(', ',$field_names).") VALUES (".join(', ',$values).")";

	return $generate_only ? $query : $this->query($query);
}


/**
 * The update method simplifies updating data in a table.
 * 
 * $where is used if you wish to make conditions for the update.
 * 
 * See {@link Database::insert() insert()} for additional information. 
 *
 * @param string $table
 * @param array $data
 * @param unknown_type $where
 * @param boolean $escape_data
 * @param boolean $generate_only
 * @return string|DatabaseResult
 * @see Database::insert()
 */
public function update($table, array $data = array(), $where = null, $escape_data = true, $generate_only = false)
{
	if(count($data) < 1) return false;

	$sets = array();
	foreach($data as $field_name => $value)
	{
		$sets[] = "{$field_name}='".($escape_data ? $this->escape_string($value) : $value)."'";
	}

	$where = !empty($where) ? " WHERE {$where}" : null;
	$query = "UPDATE {$table} SET ".join(',',$sets).$where;

	return $generate_only ? $query : $this->query($query);
}

/**
 * @access public
 * @return integer|boolean
 * @see DatabaseResult::affected_rows()
 */
public function affected_rows()
{
	if($this->last_result instanceof DatabaseResult) return $this->last_result->affected_rows();
	else return false;
}

/**
 * @access public
 * @return integer|boolean
 * @see DatabaseResult::num_rows()
 */
public function num_rows()
{
	if($this->last_result instanceof DatabaseResult) return $this->last_result->num_rows();
	else return false;
}

/**
 * @access public
 * @return array|boolean
 * @see DatabaseResult::fetch_assoc()
 */
public function fetch_assoc()
{
	if($this->last_result instanceof DatabaseResult) return $this->last_result->fetch_assoc();
	else return false;
}

/**
 * @access public
 * @return array|boolean
 * @see DatabaseResult::fetch_num_array()
 */
public function fetch_num_array()
{
	if($this->last_result instanceof DatabaseResult) return $this->last_result->fetch_num_array();
	else return false;
}

/**
 * @access public
 * @return void|boolean
 * @param integer $row_number
 * @see DatabaseResult::seek()
 */
public function seek($row_number)
{
	if($this->last_result instanceof DatabaseResult) return $this->last_result->seek($row_number);
	else return false;
}

/**
 * @access public
 * @return void|boolean
 * @see DatabaseResult::free()
 */
public function free()
{
	if($this->last_result instanceof DatabaseResult) return $this->last_result->free();
	else return false;
}

/**
 * This function will handle the connection to the database and must
 * be implemented in a child class. This is called by
 * {@link Database::__construct the constructor}.
 *
 * @abstract
 * @access protected
 * @see Database::__construct()
 */
abstract protected function connect();

/**
 * This runs a query. An instance of DatabaseResult will be returned and
 * this object will be stored in {@link Database::$last_result}.
 * 
 * Usage examples:
 * <pre>print_r($db->query("EXPLAIN SELECT * FROM users")->fetch_assoc());</pre>
 * <pre>
 * $db->query("SELECT username FROM users");
 * while($user = $db->fetch_assoc())
 * {
 * 	echo "{$user['username']}<br />";
 * }
 * </pre>
 *
 * @abstract
 * @param string $sql
 * @return DatabaseResult|boolean
 */
abstract public function query($sql);

/**
 * Escapes a string to prepare it for usage in a query.
 *
 * @abstract
 * @access public
 * @param string $string
 * @return string
 */
abstract public function escape_string($string);

/**
 * Gets the latest error message
 *
 * @abstract
 * @access public
 * @return string
 */
abstract public function error_message();

/**
 * Gets the latest error number
 *
 * @abstract
 * @access public
 * @return integer
 */
abstract public function error_number();
}

/**
* MySQL driver for Database.
*
* @author Daniel Egeberg
*/
class Database_MySQL extends Database
{
/**
 * @access protected
 * @see Database::connect()
 */
protected function connect()
{
	$connect_function_name = $this->persistent ? 'mysql_pconnect' : 'mysql_connect';

	$this->db_link = @$connect_function_name($this->host, $this->username, $this->password);
	if(!is_resource($this->db_link)) throw new Exception_Database($this, "Failed connecting to database");
	if(!mysql_select_db($this->database, $this->db_link)) throw new Exception_Database($this, "Failed to select database");
}

/**
 * @access public
 * @param string $sql
 * @return DatabaseResult|boolean
 * @see Database::query()
 */
public function query($sql)
{
	$timer = new Timer();
	$result = @mysql_query($sql);
	$end_time = $timer->get_time();

	if(!is_resource($result))
	{
		throw new Exception_Database($this, $sql);
	}

	$this->last_result = DatabaseResult::factory('MySQL', $this, $result, $sql, $end_time);

	return $this->last_result;
}

/**
 * @access public
 * @param string $string
 * @return string
 * @see Database::escape_string()
 */
public function escape_string($string)
{
	return mysql_real_escape_string($string, $this->db_link);
}

/**
 * @access public
 * @return string
 * @see Database::error_message()
 */
public function error_message()
{
	return mysql_error();
}

/**
 * @access public
 * @return integer
 * @see Database::error_number()
 */
public function error_number()
{
	return mysql_errno();
}
}

/**
* Holds the result of a database query
*
* @abstract
* @author Daniel Egeberg
*/
abstract class DatabaseResult
{
/**
 * The instance of the Database class from which the query was executed
 *
 * @access protected
 * @var Database
 */
protected $db;

/**
 * Holds a kind of resource related to the query. What kind of
 * resource depends on what kind of database driver that is being
 * used.
 *
 * @access protected
 * @var mixed
 */
protected $query_resource;

/**
 * This holds the query that was executed.
 *
 * @access protected
 * @var string
 * @see DatabaseResult::get_query()
 */
protected $query;

/**
 * The time it took to execute this query
 *
 * @access protected
 * @var float
 * @see DatabaseResult::get_time()
 */
protected $time;

/**
 * The constructor sets various variables.
 *
 * @access public
 * @param Database $db
 * @param mixed $query_resource
 * @param string $query
 * @param float $time
 */
public function __construct(Database $db, $query_resource, $query, $time)
{
	$this->db				= $db;
	$this->query_resource	= $query_resource;
	$this->query			= $query;
	$this->time				= $time;
}

/**
 * The factory is used to get a specific children of DatabaseResult.
 * 
 * $type could e.g. be MySQL or SQLite
 *
 * @param string $type
 * @param Database $db
 * @param mixed $query_resource
 * @param string $query
 * @param float $time
 * @return DatabaseResult
 */
public static function factory($type, Database $db, $query_resource, $query, $time)
{
	$class_name = "DatabaseResult_{$type}";
	return new $class_name($db, $query_resource, $query, $time);
}

/**
 * Returns the SQL for the query
 *
 * @access public
 * @return string
 * @see DatabaseResult::$query
 */
public function get_query() { return $this->query; }

/**
 * Returns the time it took to execute this query
 *
 * @access public
 * @return float
 * @see DatabaseResult::$time
 */
public function get_time()  { return $this->time;  }


/**
 * Returns the number of rows the query affected
 *
 * @abstract
 * @access public
 * @return integer
 */
abstract public function affected_rows();

/**
 * Returns the number of rows the query returned
 *
 * @abstract
 * @access public
 * @return integer
 */
abstract public function num_rows();

/**
 * Fetches a row as an associative array
 *
 * @abstract
 * @access public
 * @return array
 */
abstract public function fetch_assoc();

/**
 * Fetches a row as an enumerated array
 *
 * @abstract
 * @access public
 * @return array
 */
abstract public function fetch_num_array();

/**
 * Jumps to a specific returned row starting from 0 (zero).
 *
 * @abstract
 * @access public
 * @param integer $row_number
 */
abstract public function seek($row_number);

/**
 * Will free all memory associated with this result.
 *
 * @abstract
 * @access public
 */
abstract public function free();
}


/**
* Database result for MySQL
*
* @author Daniel Egeberg
*/
class DatabaseResult_MySQL extends DatabaseResult
{
/**
 * @access public
 * @return integer
 * @see DatabaseResult::affected_rows()
 */
public function affected_rows()
{
	return (int) @mysql_num_rows($this->query_resource);
}

/**
 * @access public
 * @return integer
 * @see DatabaseResult::num_rows()
 */
public function num_rows()
{
	return (int) @mysql_num_rows($this->query_resource);
}

/**
 * @access public
 * @return array
 * @see DatabaseResult::fetch_assoc()
 */
public function fetch_assoc()
{
	return (array) @mysql_fetch_assoc($this->query_resource);
}

/**
 * @access public
 * @return array
 * @see DatabaseResult::fetch_num_array
 */
public function fetch_num_array()
{
	return (array) @mysql_fetch_row($this->query_resource);
}

/**
 * @access public
 * @param integer $row_number
 * @see DatabaseResult::seek()
 */
public function seek($row_number)
{
	mysql_data_seek($this->query_resource, (int) $row_number);
}

/**
 * @access public
 * @see DatabaseResult::free()
 */
public function free()
{
	mysql_free_result($this->query_resource);
}
}

/**
* A database specific exception class. Doesn't really do
* anything except stopping execution and outputting the
* error.
* 
* @author Daniel Egeberg
* @todo Make it do something useful...
*/
class Exception_Database extends Exception
{
/**
 * Constructor...
 *
 * @magic
 * @param Database $db
 * @param string $message
 * @param integer $code
 */
public function __construct(Database $db, $message = null, $code = 0)
{
	parent::__construct($message, $code);

	die("Database Error ({$message}): {$db->error_message()}");
}

// do stuff,,,?
}

$db = Database::factory('MySQL', 'localhost', 'root', '', 'some_table');
print_r($db->query("EXPLAIN SELECT * FROM users")->fetch_assoc());

$db->query("SELECT username FROM users");
while($user = $db->fetch_assoc())
{
echo "{$user['username']}<br />";
}
?>

 

Classes should obviously be placed in separate files and the factory methods should be changed to fit this.

 

Note: It's not tested very much.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.