GlassCasket Posted July 18, 2007 Share Posted July 18, 2007 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! Quote Link to comment https://forums.phpfreaks.com/topic/60583-trying-to-a-new-singleton-database-class/ Share on other sites More sharing options...
KevinM1 Posted July 18, 2007 Share Posted July 18, 2007 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. Quote Link to comment https://forums.phpfreaks.com/topic/60583-trying-to-a-new-singleton-database-class/#findComment-301415 Share on other sites More sharing options...
Daniel0 Posted July 18, 2007 Share Posted July 18, 2007 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 :-\ Quote Link to comment https://forums.phpfreaks.com/topic/60583-trying-to-a-new-singleton-database-class/#findComment-301796 Share on other sites More sharing options...
Jenk Posted July 19, 2007 Share Posted July 19, 2007 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. Quote Link to comment https://forums.phpfreaks.com/topic/60583-trying-to-a-new-singleton-database-class/#findComment-302148 Share on other sites More sharing options...
Mastodont Posted July 26, 2007 Share Posted July 26, 2007 You could join getInstance and Connect, could'nt you? http://www.tozz.org/php/simple-database-connection-using-the-singleton-pattern-in-php Quote Link to comment https://forums.phpfreaks.com/topic/60583-trying-to-a-new-singleton-database-class/#findComment-308168 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.