1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
<?php class DB { //connection variables protected $dbhost = 'localhost'; protected $dbuser = 'root'; protected $dbpass = ''; protected $dbname = 'dbname'; //normal global resources protected $db = null; protected static $instance = null; /** * Singleton pattern for instantiating the DB class */ public static function GetInstance() { if(!self::$instance) { self::$instance = new DB; } return self::$instance; } protected function __construct() { if(($db = @mysql_connect($this->dbhost, $this->dbuser, $this->dbpass)) === false) { trigger_error('There was an error connecting to the server.'); exit; } if((@mysql_select_db($this->dbname, $db)) === false) { trigger_error('There was an error selecting the database.'); exit; } $this->db = $db; } /** * simple method for sanitizing SQL query strings. */ public function Clean($string) { if(get_magic_quotes_gpc()) { $string = stripslashes($string); } return mysql_real_escape_string($string); } /** * DB class method call to the Query child class. * SELECT queries only * Returns an object. */ public function Query($statement) { return new Query($statement, $this->db); } /** * DB class method call to the Execute child class. * INSERT/UPDATE/DELETE queries only * Returns number of rows affected. */ public function Execute($statement) { return new Execute($statement, $this->db); } /** * Used to get the last inserted record */ public function InsertID() { return mysql_insert_id($this->link); } /** * The transactional functions are giving me more of a headache than * I sould care to have. The general idea behind what I want to do * with them is be able to pass an array of SQL queries into one * main method call, which in turn calls its child methods. * * The issue I have with this is that there are instances where I * dont want to base a Commit / Rollback on whether or not the * queries succeed or fail, but perhaps the time of day, or the * privelage level of the user running the queries, etc. */ public function Transaction($queryArray) { /** * this method call will return a new instance of the * Transaction CLass. Operations are documented within * the Transaction Class. */ return new Transaction($queryArray, $this->db); } public function __destruct() { @mysql_close($this->db); } } /** * These are separate classes for the reason that I would like * to be able to edit them with as little distruption to the * flow of the parent class as possible. */ /** * Query child class. Used for running SELECT queries. * Called exclusively by the DB parent class in the Query method */ class Query { protected $result; public function __construct($statement, $link) { if(($this->result = mysql_query($statement, $link)) === false) { trigger_error('There was an error in processing the Query method: '. mysql_error()); exit; } } public function Fetch($class = null) { return @mysql_fetch_object($this->result); } public function __destruct() { @mysql_free_result($this->result); } } /** * Execute child class. Used for running INSERT/UPDATE/DELETE queries. * Called exclusively by the DB parent class in the Execute method */ class Execute { public function __construct($statement, $link) { if((@mysql_query($statement, $link)) == false) { trigger_error('There was an error processing the Execute method: '. mysql_error()); exit; } return @mysql_affected_rows($link); } } /** * Transaction child class. Used for transactional queries. * Called exclusively by the DB parent class in the Transaction method */ class Transaction { public function __construct($queryArray, $link) { /** * This is not working at all the way I want it to. * * Essentially what it is doing, is running the first * query, then basing the Commit / Rollback on the * outcome of that single query. That's no good. * * I can see _why_ its not working, but that doesn't * really help me to fix it. * * $hold is set to 1 as its starting value, and as * the loop progresses it either changes that or * doesnt, depending on the outcome. What it seems * to be doing is running it once, and deciding * "Hey! the query worked!, lets commit changes!". */ $hold = 1; $this->Begin(); foreach($queryArray as $query) { @mysql_query($query, $link); if(@mysql_affected_rows($link) == 0) { $hold = 0; } } if($hold == 0) { $this->Rollback(); return false; } else { $this->Commit(); return true; } } private function Begin() { @mysql_query('BEGIN', $link); } private function Commit() { @mysql_query('COMMIT', $link); } private function Rollback() { @mysql_query('ROLLBACK', $link); } } ?>
Refactorings
No refactoring yet !
Maciej Piechotka
July 21, 2008, July 21, 2008 19:24, permalink
1. Why not PEAR DB?
2. Why not MySQLi with precompiled queries (it has everything you need but faster and in standard)?
Ishkur
July 22, 2008, July 22, 2008 03:36, permalink
Well if I wanted to go that route I could just as well use PDO and be done with the whole class, but thats not really what I want. And to be completely honest I dont really like Pear, it just feels like there's so much overhead. I just sorta wanted the transactional functions to work.... the child methods themselves work, thats not an issue, but the constructor method is whats killing me.
Maciej Piechotka
August 6, 2008, August 06, 2008 21:23, permalink
Sorry for late response - so what do you want which is not covered by MySQLi?
For the most part, this class does everything I need. I've been updating it to PHP5, and have noticed a really rather big issue with my Transaction support: it simple doesnt work.
I've explained the issue in comments in the code.