Jump to content

Trying to a new singleton Database class


GlassCasket

Recommended Posts

I'm new to OOP PHP5 and I'm trying to use the singleton pattern for my Database class. Here is my current code (yes, the getInstance is from the PHP manual):

<?php

final class Database {
private static instance = null;
private $username, $password, $host;

/*
 * Prevent an object from being constructed
 */	
private __construct() {

}

private __destruct() {

}

/*
 * Return the instance of this class
 */
public static function getInstance() {
	if(is_null(self::$instance)) {
		self::$instance = new Database();
	}
	return self::$instance;
}

protected function connect($username = "test", $password = "test", $host = "test") {

}

protected function query($query) {

}
}

?>

My questions are:

- How can I restrict this to only one connection which every thing in the file can use?

- How can I make the quiery() function? I'm not quite sure what to return.

 

This is only suppose to be a basic database class which will allow me to connect and run queries. If anyone has any suggestions and ideas, don't hesitate to write them out. :)

 

Thanks!

Link to comment
Share on other sites

Maybe something like this will work:

<?php

final class Database {
   private static $instance = null;
   private static $connection;
   private $username, $password, $host;

   /*
    * Prevent an object from being constructed
    */	

   private __construct() {		
   }

   private __destruct() {		
   }

   /*
    * Return the instance of this class
    */

   public static function getInstance() {
      if(is_null(self::$instance)) {
         self::$instance = new Database();
      }

      return self::$instance;
   }

   protected function connect($username = "test", $password = "test", $host = "test") { //needs error handling
      if(empty(self::$connection)){
         self::$connection = mysql_connect($host, $username, $password);
      }

      return self::$connection;
   }

   protected function query($query) {  //needs error handling
      $result = mysql_query($query);
      return $result;
   }
}

?>

 

Of course, this isn't tested code, but I don't see why you couldn't treat the database connection as another static member which is only created if it's empty, and returned all other times.

Link to comment
Share on other sites

Why are you declaring the methods protected? I'd do something like this:

<?php
final class Database {
private static $instance = null;

protected $username;
protected $password;
protected $host;
protected $database;

protected $connection;
protected $last_result;

private function __construct()
{

}

public function __destruct()
{

}

public static function getInstance()
{
	if(is_null(self::$instance))
	{
		self::$instance = new Database();
	}
	return self::$instance;
}

public function connect($username, $password, $host, $database)
{
	$this->username	= $username;
	$this->password	= $password;
	$this->host		= $host;
	$this->database	= $database;

	$this->connection = @mysql_connect($this->username, $this->password, $this->password);
	if(!$this->connection) throw new Exception("Failed connecting to database: ".mysql_error());

	$select = mysql_select_db($this->database, $this->connection);
	if(!$select) throw new Exception("Failed selecting database: ".mysql_error());
}

public function query($query)
{
	$this->last_result = @mysql_query($query, $this->connection);
	return $this->last_result;
}

public function fetch_row($result=null)
{
	$result = is_resource($result) ? $result : $this->last_result;

	return mysql_fetch_assoc($result);
}

public function get_num_rows($result=null)
{
	$result = is_resource($result) ? $result : $this->last_result;

	return mysql_num_rows($result);
}

public function fetch_result($query)
{
	$this->query($query);
	$result = $this->fetch_row();
	$result['db_rows_returned'] = $this->get_num_rows();

	return $result;
}

public function insert($table, $values=array())
{
	$started = 0;
	foreach($values as $field => $value)
	{
		if($started == 0)
		{
			$values_used	= $field;
			$actual_values	= "'{$value}'";
			$started		= 1;
		}
		else {
			$values_used	.= ",{$field}";
			$actual_values	.= ",'{$value}'";
		}
	}

	$result = $this->query("INSERT INTO {$table} ({$values_used}) VALUES({$actual_values})");

	return $result;
}

public function update($table, $values=array(), $where)
{
	$sets = array();
	foreach($values as $field => $value)
	{
		$sets[] = "{$field}='{$value}'";
	}
	$set = join(',',$sets);

	$where_sql = empty($where) ? null : " WHERE {$where}";

	$result = $this->query("UPDATE {$tbl} SET {$set}{$where_sql}");

	return $result;
}

public function errno()
{
	return mysql_errno();
}

public function error()
{
	return mysql_error();
}
}

class DBException extends Exception
{
public function __construct($db) // do something a little more "advanced" here
{
	die("Database error [{$db->errno()}]: {$db->error()}");
}
}
?>

 

Hmm... added a few extra methods :-\

Link to comment
Share on other sites

Database accessors should not be singleton. Why? Multiple user sessions will need multiple connections; else you will find your applications will have (database) session collisions.

 

EDIT: Infact, you can ignore this post. I'd forgotten PHP is not state persistent so the above does not apply.

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.