eddedwards Posted December 7, 2008 Share Posted December 7, 2008 Ive been studying abstract classes and interfaces and was trying to come up with a good way of using it for a database handler. I want it for a cms project im doing and would like to know if this is a good way of doing it. c_db_handler.php: 1. Function for getting the handler. 2. Abstract db_handler class. 3+ Supported db extension classes. (Currently working with SQLite and MySql skeleton in place) <?php function get_db_handler ($db_type) { $args = func_get_args(); switch ($args[0]) { case "SQLite" : if (func_num_args() == 3) return new sqlite_handler($args[1],$args[2]); break; case "MySQL" : return new mysql_handler(); break; } } abstract class db_handler { // Possible data connection requirements. protected $db_name; protected $db_path; protected $db_perm; protected $db_server; protected $db_user; protected $db_pass; // DB Handler Variables. protected $handle; protected $result; protected $errors = array(); protected $result_type; abstract protected function connect(); abstract protected function disconnect(); abstract protected function parse_query($sql); abstract protected function parse_query_exec($sql); abstract public function fetch_result($fetch_type); function set_data($name=NULL,$path=NULL,$perm=NULL,$server=NULL,$user=NULL,$pass=NULL,$res_type=SQLITE_ASSOC) { if ($name) $this->db_name = $name; if ($path) $this->db_path = $path; if ($perm) $this->db_perm = $perm; if ($server) $this->db_server = $server; if ($user) $this->db_user = $user; if ($pass) $this->db_pass = $pass; $this->result_type = $res_type; } } class sqlite_handler extends db_handler { function __construct($db_path,$db_name) { $this->set_data($db_name,$db_path,0666,NULL,NULL,NULL); } function connect() { if ($this->handle = sqlite_open($this->db_path . $this->db_name,$this->db_perm,&$this->errors[])) { return true; } else { return false; } } function disconnect() { sqlite_close($this->handle); } function parse_query($sql) { if ($this->result = sqlite_query($this->handle,$sql,$this->result_type,&$this->errors[])) { return true; } else { return false; } } function parse_query_exec ($sql) { if ($this->result = sqlite_exec($this->handle,$sql,&$this->errors[])) { return true; } else { return false; } } function fetch_result($fetch_type) { $data = false; switch (strtolower($fetch_type)) { case "all" : if ($data = sqlite_fetch_all($this->result, $this->result_type)) return $data; break; case "array" : if ($data = sqlite_fetch_array($this->result, $this->result_type)) return $data; break; case "string" OR "single" : if ($data = sqlite_fetch_single($this->result)) return $data; break; } return $data; } } class mysql_handler extends db_handler { function connect() { } function disconnect() { } function parse_query($sql) { } function parse_query_exec ($sql) { } function fetch_result($fetch_type) { } } ?> index.php: Usage code. <?php include_once("./inc/c_db_handler.php"); $sql[1] = <<<SQL BEGIN; CREATE TABLE test ( foo VARCHAR(10), bar VARCHAR(10) ); INSERT INTO test (foo,bar) VALUES ("test1","test2"); COMMIT; SQL; $sql[2] = <<<SQL SELECT * FROM test; SQL; $db = get_db_handler("SQLite",NULL,":memory:"); $db->connect(); $db->parse_query_exec($sql[1]); $db->parse_query($sql[2]); //$end = $db->fetch_result("all"); while ($row = $db->fetch_result("array") ) { $end .= "<pre>" . print_r($row,true) . "</pre>"; } $db->disconnect(); echo "<pre>" . print_r($db,true) . "</pre>"; echo "<pre>" . print_r($end,true) . "</pre>"; ?> output of this test: sqlite_handler Object ( [db_name:protected] => :memory: [db_path:protected] => [db_perm:protected] => 438 [db_server:protected] => [db_user:protected] => [db_pass:protected] => [handle:protected] => Resource id #3 [result:protected] => Resource id #4 [errors:protected] => Array ( [0] => [1] => [2] => ) [result_type:protected] => 1 ) Array ( [foo] => test1 [bar] => test2 ) Quote Link to comment Share on other sites More sharing options...
corbin Posted December 7, 2008 Share Posted December 7, 2008 I don't like how get_db_handler is a function floating around in the global scope. function fetch_result($fetch_type) { $data = false; switch (strtolower($fetch_type)) { case "all" : if ($data = sqlite_fetch_all($this->result, $this->result_type)) return $data; break; case "array" : if ($data = sqlite_fetch_array($this->result, $this->result_type)) return $data; break; case "string" OR "single" : if ($data = sqlite_fetch_single($this->result)) return $data; break; } return $data; } That just seems kinda... Not elegant for lack of a better word. Setting $res_type earlier and then passing an arg again and what not. Also, all the switching.... I would probably put each in its own function. fetch_array(), fetch_assoc(), fetch_row(), so on. I don't remember if I saw anything else when I read through it.... Don't feel like glancing through it again, so I'm going to assume everything else was good ;p. Quote Link to comment Share on other sites More sharing options...
eddedwards Posted December 13, 2008 Author Share Posted December 13, 2008 Cheers for the input. Id like some clarification if possible. 1: get_db_handler was in the global scope because I could figure out a way of doing it another way. I need to pass a database type from a config array then load the right extension. I didn't think it would work from inside the db_handler class or its extensions unless something like this is possible: <?php class db_h { var $db_type; function __construct($type) { $class = $type . "_h"; $this->db_type = new $class(); } } class sqlite_h { } $test = new db_h("sqlite"); ?> 2: I can see what you mean about the set_data & the switching though I shall look into tidying that up. Thanks again im going to go test my theory. Quote Link to comment Share on other sites More sharing options...
corbin Posted December 13, 2008 Share Posted December 13, 2008 Yup, that's possible. Quote Link to comment 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.