├── LICENSE
├── README
├── mysqldatabase.php
└── mysqlresultset.php
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2011, Micah Carrick
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | Redistributions of source code must retain the above copyright notice, this list
8 | of conditions and the following disclaimer. Redistributions in binary form must
9 | reproduce the above copyright notice, this list of conditions and the following
10 | disclaimer in the documentation and/or other materials provided with the
11 | distribution.
12 |
13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | PHP MySQL Database Class
2 | ========================
3 |
4 | Copyright (c) 2011 Micah Carrick
5 | All Rights Reserved.
6 |
7 | PHP MySQL Database Class is singleton pattern object which serves as a MySQL
8 | database wrapper and an iterator result set object. This project was developed
9 | as a follow up to my older, PHP4 database class from 2004.
10 |
11 |
12 | Basic Usage
13 | -----------
14 | For a more detailed explanation, consult the phpDocumentor docstrings within
15 | the source code or visit http://www.micahcarrick.com/php5-mysql-database-class.html
16 |
17 | Here are some simple examples:
18 |
19 | // get the database singleton instance
20 | $db = MySqlDatabase::getInstance();
21 |
22 | // connect
23 | try {
24 | $db->connect('localhost', 'username', 'password', 'database_name');
25 | }
26 | catch (Exception $e) {
27 | die($e->getMessage());
28 | }
29 |
30 | // iterate a resultset
31 | foreach ($db->iterate("SELECT foo FROM bar LIMIT 10") as $row) {
32 | echo $row->foo;
33 | }
34 |
35 | // get just one row
36 | $count = $db->fetchOne("SELECT COUNT(*) FROM foo");
37 |
38 | // import from a file (use with caution!)
39 | $num = $db->importSqlFile('test-data.sql');
40 | echo "Imported $num statements.
";
41 |
--------------------------------------------------------------------------------
/mysqldatabase.php:
--------------------------------------------------------------------------------
1 | Getting Started
18 | *
19 | * $db = MySqlDatabase::getInstance();
20 | *
21 | * try {
22 | * $db->connect('localhost', 'user', 'password', 'database_name');
23 | * }
24 | * catch (Exception $e) {
25 | * die($e->getMessage());
26 | * }
27 | *
28 | *
29 | * @package mysql-database
30 | * @author Micah Carrick
31 | * @copyright (c) 2010 - Micah Carrick
32 | * @version 2.0
33 | * @license BSD
34 | */
35 | class MySqlDatabase
36 | {
37 | /**
38 | * The MySQL link identifier created by {@link connect()}
39 | *
40 | * @var resource
41 | */
42 | public $link;
43 |
44 | /**
45 | * @var string
46 | */
47 | private $conn_str;
48 |
49 | /**
50 | * @var MySqlDatabase
51 | */
52 | private static $instance;
53 |
54 | const MYSQL_DATE_FORMAT = 'Y-m-d';
55 | const MYSQL_TIME_FORMAT = 'H:i:s';
56 | const MYSQL_DATETIME_FORMAT = 'Y-m-d H:i:s';
57 |
58 | const INSERT_GET_AUTO_INCREMENT_ID = 1;
59 | const INSERT_GET_AFFECTED_ROWS = 2;
60 |
61 | /**
62 | * Constructor
63 | *
64 | * Private constructor as part of the singleton pattern implementation.
65 | */
66 | private function __construct() {}
67 |
68 | /**
69 | * Connect
70 | *
71 | * Establish a connection to a MySQL database. Returns the MySQL link
72 | * link identifier or throws an exception if there is an error.
73 | *
74 | *
75 | * // get an instance of the Database singleton
76 | * $db = MySqlDatabase::getInstance();
77 | *
78 | * // connect to a MySQL database (use your own login information)
79 | * try {
80 | * $db->connect('localhost', 'user', 'password', 'database_name');
81 | * }
82 | * catch (Exception $e) {
83 | * die($e->getMessage());
84 | * }
85 | *
86 | *
87 | * @param string
88 | * @param string
89 | * @param string
90 | * @param string
91 | * @param boolean
92 | * @return resource
93 | */
94 | public function connect($host, $user, $password, $database=false, $persistant=false)
95 | {
96 | if ($persistant) {
97 | $this->link = @mysql_pconnect($host, $user, $password);
98 | } else {
99 | $this->link = @mysql_connect($host, $user, $password);
100 | }
101 |
102 | if (!$this->link)
103 | {
104 | throw new Exception('Unable to establish database connection: '
105 | .mysql_error());
106 | }
107 |
108 | if ($database) $this->useDatabase($database);
109 |
110 | $version = mysql_get_server_info();
111 | $this->conn_str = "'$database' on '$user@$host' (MySQL $version)";
112 |
113 | return $this->link;
114 | }
115 |
116 | /**
117 | * Delete
118 | *
119 | * Executes the DELETE statement specified in the query and returns the
120 | * value from either the PHP {@link mysql_affected_rows()} function. Throws
121 | * and exception if there is a MySQL error in the query.
122 | *
123 | * Note: With MySQL versions prior to 4.1.2, the affected rows on DELETE
124 | * statements with no WHERE clause is 0. See {@link mysql_affected_rows()}
125 | * for more information.
126 | *
127 | * @param string
128 | * @return integer
129 | */
130 | public function delete($query)
131 | {
132 | return $this->updateOrDelete($query);
133 | }
134 |
135 | /**
136 | * Get Connection String
137 | *
138 | * Gets a string representing the connection.
139 | *
140 | *
141 | * echo $db->getConnectionString();
142 | * // example output: 'test_database' on 'web_user@localhost' (MySQL 5.1.47)
143 | *
144 | *
145 | * @return string
146 | */
147 | public function getConnectionString()
148 | {
149 | return $this->conn_str;
150 | }
151 |
152 | /**
153 | * Get Instance
154 | *
155 | * Gets the singleton instance for this object. This method should be called
156 | * statically in order to use the Database object:
157 | *
158 | *
159 | * $db = MySqlDatabase::getInstance();
160 | *
161 | *
162 | * @return MySqlDatabase
163 | */
164 | public static function getInstance()
165 | {
166 | if (!isset(self::$instance))
167 | {
168 | self::$instance = new MySqlDatabase();
169 | }
170 |
171 | return self::$instance;
172 | }
173 |
174 | /**
175 | * Fetch One From Each Row
176 | *
177 | * Convenience method to get a single value from every row in a given
178 | * query. This is usefull in situations where you know that the result will
179 | * only have only one column of data and you need that all in a simple
180 | * array.
181 | *
182 | *
183 | *
184 | * $query = "SELECT name FROM users";
185 | * $names = $db->fetchOneFromEachRow($query);
186 | * echo 'Users: ' . implode(', ', $names);
187 | *
188 | *
189 | * @param string
190 | * @return array
191 | */
192 | public function fetchOneFromEachRow($query)
193 | {
194 | $rval = array();
195 |
196 | foreach ($this->iterate($query, MySqlResultSet::DATA_NUMERIC_ARRAY) as $row) {
197 | $rval[] = $row[0];
198 | }
199 |
200 | return $rval;
201 | }
202 |
203 | /**
204 | * Fetch One Row
205 | *
206 | * Convenience method to get a single row from a given query. This is
207 | * usefull in situations where you know that the result will only contain
208 | * one record and therefore do not need to iterate over it.
209 | *
210 | * You can
211 | * optionally specify the type of data to be returned (object or array)
212 | * using one of the MySqlResultSet Data Constants. The default is
213 | * {@link MySqlResultSet::DATA_OBJECT}.
214 | *
215 | *
216 | * // get one row of data
217 | * $query = "SELECT first, last FROM users WHERE user_id = 24 LIMIT 1";
218 | * $row = $db->fetchOneRow($query);
219 | * echo $row->foo;
220 | * echo $row->bar;
221 | *
222 | *
223 | * @param string
224 | * @param integer
225 | * @return mixed
226 | */
227 | public function fetchOneRow($query, $data_type=MySqlResultSet::DATA_OBJECT)
228 | {
229 | $result = new MySqlResultSet($query, $data_type, $this->link);
230 | $result->rewind();
231 | $row = $result->current();
232 |
233 | return $row;
234 | }
235 |
236 | /**
237 | * Fetch One
238 | *
239 | * Convenience method to get a single value from a single row. Returns the
240 | * value if the query returned a record, false if there were no results, or
241 | * throws an exception if there was an error with the query.
242 | *
243 | *
244 | * // get the number of records in the 'users' table
245 | * $count = $db->fetchOne("SELECT COUNT(*) FROM users");
246 | *
247 | *
248 | * @param string
249 | * @return mixed
250 | */
251 | public function fetchOne($query)
252 | {
253 | $result = new MySqlResultSet($query, MySqlResultSet::DATA_NUMERIC_ARRAY,
254 | $this->link);
255 | $result->rewind();
256 | $row = $result->current();
257 |
258 | if (!$row) return false;
259 | else return $row[0];
260 | }
261 |
262 | /**
263 | * Import SQL File
264 | *
265 | * Runs the queries defined in an SQL script file. The double-hyphen style
266 | * comments must have a single space after the hyphens. Hash style comments
267 | * and C-style comments are also supported.
268 | *
269 | * An optional user callback function can be specified to get information
270 | * about each MySQL statement. The user callback function takes 3
271 | * parameters: the line number as an integer, the query as a string, and the
272 | * result of the query as a boolean.
273 | *
274 | *
275 | * function import_sql_callback($line_number, $sql_query, $result)
276 | * {
277 | * echo "Line $line_number: $sql_query ";
278 | * if ($result) echo "(OK)
";
279 | * else echo "(FAIL)
";
280 | * }
281 | *
282 | *
283 | * You can optionally specify whether or not to abort importing statements
284 | * when an SQL error occurs (defaults to 'true') in which case an exception
285 | * will be thrown for any MySQL error.
286 | *
287 | * Returns the number of queries executed from the script or throws an
288 | * exception if there is an error.
289 | *
290 | *
291 | * // no callback, throw exception on MySQL errors
292 | * $number = $db->importSqlFile('queries.sql');
293 | *
294 | * // callback for each query, skip queries with MySQL errors
295 | * $number = $db->importSqlFile('queries.sql', 'import_sql_callback', false);
296 | *
297 | *
298 | * TODO: Ensure this works with huge files. Might need to use fopen()
299 | *
300 | * @param string
301 | * @param string
302 | * @param boolean
303 | * @return integer
304 | */
305 | public function importSqlFile($filename, $callback=false, $abort_on_error=true)
306 | {
307 | if ($callback && !is_callable($callback)) {
308 | throw new Exception("Invalid callback function.");
309 | }
310 |
311 | $lines = $this->loadFile($filename);
312 |
313 | $num_queries = 0;
314 | $sql_line = 0;
315 | $sql = '';
316 | $in_comment = false;
317 |
318 | foreach ($lines as $num => $line) {
319 |
320 | $line = trim($line);
321 | $num++;
322 | if (empty($sql)) $sql_line = $num;
323 |
324 | // ignore comments
325 |
326 | if ($in_comment) {
327 | $comment = strpos($line, '*/');
328 |
329 | if ($comment !== false) {
330 | $in_comment = false;
331 | $line = substr($line, $comment+2);
332 | } else {
333 | continue;
334 | }
335 |
336 | } else {
337 |
338 | $comment = strpos($line, '/*');
339 |
340 | if ($comment !== false) {
341 |
342 | if (strpos($line, '*/') === false) {
343 | $in_comment = true;
344 | }
345 |
346 | $line = substr($line, 0, $comment);
347 |
348 | } else {
349 |
350 | // single line comments
351 |
352 | foreach (array('-- ', '#') as $chars) {
353 | $comment = strpos($line, $chars);
354 |
355 | if ($comment !== false) {
356 | $line = substr($line, 0, $comment);
357 | }
358 | }
359 | }
360 | }
361 |
362 | // check if the statement is ready to be queried
363 |
364 | $end = strpos($line, ';');
365 |
366 | if ($end === false) {
367 | $sql .= $line;
368 | } else {
369 | $sql .= substr($line, 0, $end);
370 | $result = $this->quickQuery($sql);
371 | $num_queries++;
372 |
373 | if (!$result && $abort_on_error) {
374 | $file = basename($filename);
375 | $error = mysql_error($this->link);
376 | throw new Exception("Error in $file on line $sql_line: $error");
377 | }
378 |
379 | if ($callback) {
380 | call_user_func($callback, $sql_line, $sql, $result);
381 | }
382 |
383 | $sql = ''; // clear for next statement
384 |
385 | }
386 | }
387 |
388 | return $num_queries;
389 | }
390 |
391 | /**
392 | * Is Connected
393 | *
394 | * Determines if there is a connection open to the database.
395 | *
396 | * @return boolean
397 | */
398 | public function isConnected()
399 | {
400 | if (!empty($this->link)) {
401 | return @mysql_ping($this->link);
402 | } else {
403 | return false;
404 | }
405 | }
406 |
407 | // insertPhpArray
408 | // insertSqlArray
409 | // sqlval()
410 |
411 | /**
412 | * Insert
413 | *
414 | * Executes the INSERT statement specified in the query and returns the
415 | * value from either the PHP {@link mysql_insert_id()} function or the
416 | * php {@link mysql_affected_rows()} function depending on the value of the
417 | * $return_type parameter.
418 | *
419 | *
420 | * $db = MySqlDatabase::getInstance();
421 | * $query = "INSERT INTO foobar (col1, col2) VALUES (1, 2), (2, 3)";
422 | * $rows = $db->insert($query, MySqlDatabase::INSERT_GET_AFFECTED_ROWS);
423 | * echo $rows; // output: 2
424 | *
425 | *
426 | *
427 | * @param string
428 | * @param integer
429 | * @return integer
430 | */
431 | public function insert($query, $r_type=MySqlDatabase::INSERT_GET_AUTO_INCREMENT_ID)
432 | {
433 | $r = $this->query($query);
434 |
435 | if ($r_type == MySqlDatabase::INSERT_GET_AFFECTED_ROWS) {
436 | return @mysql_affected_rows($this->link);
437 | } else {
438 | return @mysql_insert_id($this->link);
439 | }
440 | }
441 |
442 | /**
443 | * DO NOT USE
444 | *
445 | * This was never finished... I don't think. The goal was to take a table
446 | * name, an array of column names, and an array of values and generate a
447 | * multiple record insert. You should not use this, but, you could help
448 | * out and finish or rewrite this method.
449 | *
450 | *
451 | * @param deprecated
452 | */
453 | public function smartInsert($table, $columns, $values)
454 | {
455 | if (empty($table) || !is_string($table)) {
456 | throw new Exception('The $table parameter must be specified as a string.');
457 | }
458 |
459 | $table_sql = '`' . @mysql_real_escape_string($table) . '`';
460 | $query = "INSERT INTO $table_sql ";
461 |
462 | // columns
463 | if (is_string($columns)) {
464 | $columns = explode(',', $columns);
465 | }
466 |
467 | if (is_array($columns)) {
468 | foreach ($columns as &$col) {
469 | if (!is_string($col)) {
470 | throw new Exception('The $columns parameter must be a string or an array of strings');
471 | }
472 | $col = @mysql_real_escape_string($col);
473 | }
474 | $column_sql = implode(',', $columns);
475 | $column_count = count($columns);
476 | } else {
477 | throw new Exception('The $columns parameter must be a string or an array of strings.');
478 | }
479 |
480 | try {
481 | $column_info = array();
482 |
483 | foreach ($this->iterate("SHOW COLUMNS FROM $table_sql") as $row) {
484 | $column_info[] = $row;
485 | }
486 | }
487 | catch (Exception $e) {
488 | throw new Exception("Could not get column information for table $table_sql.");
489 | }
490 |
491 | $query .= "($column_sql) ";
492 |
493 | // values
494 |
495 | if (is_array($values)) {
496 | for ($i=0; $i < count($values); $i++) {
497 | $info = $column_info[$i];
498 | $value = $values[i];
499 |
500 | // Where the heck did I leave off?
501 | }
502 | } else {
503 | // TODO: if only 1 column, then this will work
504 |
505 | throw new Exception('The $values parameter must be a string or an array.');
506 | }
507 |
508 | if (isset($column_count) && $column_count <> $value_count) {
509 | throw new Exception("Column count ($column_count) does not match values count ($value_count).");
510 | }
511 |
512 | $query .= "VALUES ($value_sql) ";
513 |
514 | echo $query;
515 |
516 | }
517 |
518 | /**
519 | * Iterate Result Set
520 | *
521 | * Returns a {@link MySQL_ResultSet} iteratable object for a query. The $type
522 | * parameter indicates the data being iterated should be an object,
523 | * a numerically indexed array, an associative array, or an array with
524 | * both numeric and associative indexes. Defaults to objects.
525 | *
526 | *
527 | * $sql_query = "SELECT col1, col2 FROM table";
528 | *
529 | * // iterate as objects
530 | * foreach ($db->iterate("SELECT col1, col2 FROM table") as $row) {
531 | * echo $row->col1 . '
';
532 | * echo $row->col2 . '
';
533 | * }
534 | *
535 | * // iterate as both associative and numerically indexed array
536 | * foreach ($db->iterate($sql_query, MySQL_Db::DATA_ARRAY) as $row) {
537 | * echo $row[0] . '
';
538 | * echo $row['col1'] . '
';
539 | * }
540 | *
541 | *
542 | * @param string
543 | * @param integer
544 | * @return boolean
545 | */
546 | public function iterate($sql, $data_type=MySqlResultSet::DATA_OBJECT)
547 | {
548 | return new MySqlResultSet($sql, $data_type, $this->link);
549 | }
550 |
551 | /**
552 | * Load File
553 | *
554 | * Loads the specified filename into an array of lines. Throws an exception
555 | * if there is an error.
556 | *
557 | * @param string
558 | * @return boolean
559 | */
560 | private function loadFile($filename)
561 | {
562 | if (!file_exists($filename)) {
563 | throw new Exception("File does not exist: $filename");
564 | }
565 |
566 | $file = @file($filename, FILE_IGNORE_NEW_LINES);
567 |
568 | if (!$file) {
569 | throw new Exception("Could not open $filename");
570 | }
571 |
572 | return $file;
573 | }
574 |
575 | public function query($query)
576 | {
577 | $r = @mysql_query($query, $this->link);
578 |
579 | if (!$r) {
580 | throw new Exception("Query Error: " . mysql_error());
581 | }
582 |
583 | return $r;
584 | }
585 |
586 | /**
587 | * Quick Query
588 | *
589 | * Executes a MySQL query and returns a boolean value indicating success
590 | * or failure. This method will close any resources opened from
591 | * SELECT, SHOW, DESCRIBE, or EXPLAIN statements and would not be very
592 | * usefull for those types of queries. This method is used internally for
593 | * importing SQL scripts.
594 | *
595 | * @param string
596 | * @return boolean
597 | */
598 | public function quickQuery($query)
599 | {
600 | $r = @mysql_query($query, $this->link);
601 |
602 | if (!$r) return false;
603 | if (is_resource($r)) mysql_free_result($r);
604 |
605 | return true;
606 | }
607 |
608 | /**
609 | * Update
610 | *
611 | * Executes the UPDATE statement specified in the query and returns the
612 | * value from either the PHP {@link mysql_affected_rows()} function. Throws
613 | * and exception if there is a MySQL error in the query.
614 | *
615 | * Note: The number of rows affected include only those in which the new
616 | * value was not the same as the old value. See {@link mysql_affected_rows()}
617 | * for more information.
618 | *
619 | * @param string
620 | * @return integer
621 | */
622 | public function update($query)
623 | {
624 | return $this->updateOrDelete($query);
625 | }
626 |
627 | private function updateOrDelete($query)
628 | {
629 | $r = $this->query($query);
630 | return @mysql_affected_rows($this->link);
631 | }
632 |
633 | /**
634 | * Use Database
635 | *
636 | * Selects the database to use. Throws an exception if there is an error
637 | * using the specified database.
638 | *
639 | * @param string
640 | * @return integer
641 | */
642 | public function useDatabase($database)
643 | {
644 | if (!@mysql_select_db($database, $this->link))
645 | {
646 | throw new Exception('Unable to select database: ' . mysql_error($this->link));
647 | }
648 | }
649 | }
650 |
651 |
652 |
653 | ?>
654 |
--------------------------------------------------------------------------------
/mysqlresultset.php:
--------------------------------------------------------------------------------
1 |
22 | * $db = MySqlDatabase::getInstance();
23 | * $db->connect('localhost', 'user', 'password', 'database_name');
24 | *
25 | * // $db->iterate() returns a new MySqlResultSet instance
26 | * foreach ($db->iterate("SELECT * FROM users LIMIT 100") as $row) {
27 | * print_r($row);
28 | * }
29 | *
30 | *
31 | * @package mysql-database
32 | * @author Micah Carrick
33 | * @copyright (c) 2010 - Micah Carrick
34 | * @version 2.0
35 | * @license BSD
36 | */
37 | class MySqlResultSet implements Iterator
38 | {
39 | private $query;
40 | private $result;
41 | private $index = 0;
42 | private $num_rows = 0;
43 | private $row = false;
44 | private $type;
45 |
46 | /**
47 | * Object Data
48 | *
49 | * The data will be fetched as an object, where the columns of the table
50 | * are property naems of the object. See
51 | * {@link mysql_fetch_object()}.
52 | */
53 | const DATA_OBJECT = 1;
54 |
55 | /**
56 | * Numeric Array Data
57 | *
58 | * The data will be fetched as a numerically indexed array. See
59 | * {@link mysql_fetch_row()}.
60 | */
61 | const DATA_NUMERIC_ARRAY = 2;
62 |
63 | /**
64 | * Keyed Array Data
65 | *
66 | * The data will be fetched as an associative array. See
67 | * {@link mysql_fetch_assoc()}.
68 | */
69 | const DATA_ASSOCIATIVE_ARRAY = 3;
70 |
71 | /**
72 | * Array Data
73 | *
74 | * The data will be fetched as both an associative and indexed array. See
75 | * {@link mysql_fetch_array()}.
76 | */
77 | const DATA_ARRAY = 4;
78 |
79 | /**
80 | * Constructor
81 | *
82 | * The constructor requires an SQL query which should be a query that
83 | * returns a MySQL result resource such as a SELECT query. If the query
84 | * fails or does not return a result resource, the constructor will throw
85 | * an exception.
86 | *
87 | * The optional $data_type parameter specifies how to fetch the data. One
88 | * of the data constants can be specified or the default
89 | * {@link MySqlResultSet::DATA_OBJECT} will be used.
90 | *
91 | * @param string
92 | * @param integer
93 | */
94 | public function __construct($query, $data_type=MySqlResultSet::DATA_OBJECT,
95 | $link=false)
96 | {
97 | if ($link) $this->result = @mysql_query($query, $link);
98 | else $this->result = @mysql_query($query);
99 |
100 | if (!$this->result) {
101 | throw new Exception(mysql_error());
102 | }
103 |
104 | if (!is_resource($this->result)
105 | || get_resource_type($this->result) != 'mysql result') {
106 | throw new Exception("Query does not return an mysql result resource.");
107 | }
108 |
109 | $this->query = $query;
110 | $this->num_rows = mysql_num_rows($this->result);
111 | $this->type = $data_type;
112 | }
113 |
114 | /**
115 | * Destructor
116 | *
117 | * The destructor will free the MySQL result resource if it is valid.
118 | */
119 | public function __destruct()
120 | {
121 | if (is_resource($this->result)
122 | && get_resource_type($this->result) == 'mysql result') {
123 | mysql_free_result($this->result);
124 | }
125 | }
126 |
127 | private function fetch()
128 | {
129 | if ($this->num_rows > 0) {
130 | switch ($this->type) {
131 | case MySqlResultSet::DATA_NUMERIC_ARRAY:
132 | $func = 'mysql_fetch_row';
133 | break;
134 | case MySqlResultSet::DATA_ASSOCIATIVE_ARRAY:
135 | $func = 'mysql_fetch_assoc';
136 | break;
137 | case MySqlResultSet::DATA_ARRAY:
138 | $func = 'mysql_fetch_array';
139 | default:
140 | $func = 'mysql_fetch_object';
141 | break;
142 | }
143 |
144 | $this->row = $func($this->result);
145 | $this->index++;
146 | }
147 | }
148 |
149 | public function getResultResource()
150 | {
151 | return $this->result;
152 | }
153 |
154 | public function isEmpty()
155 | {
156 | if ($this->num_rows == 0) return true;
157 | else return false;
158 | }
159 |
160 | /**
161 | * Rewind
162 | *
163 | * Rewind the Iterator to the first row of data.
164 | */
165 | public function rewind()
166 | {
167 | if ($this->num_rows > 0) {
168 | mysql_data_seek($this->result, 0);
169 | $this->index = -1; // fetch() will increment to 0
170 | $this->fetch();
171 | }
172 | }
173 |
174 | /**
175 | * Current Row
176 | *
177 | * Get the current row of data. The type of data is determined by the $type
178 | * parameter passed to the constructor.
179 | *
180 | * @return mixed
181 | */
182 | function current()
183 | {
184 | return $this->row;
185 | }
186 |
187 | /**
188 | * Key
189 | *
190 | * Get the index for the current row. The index begins at 0 with the first
191 | * row of data.
192 | *
193 | * @return integer
194 | */
195 | function key()
196 | {
197 | return $this->index;
198 | }
199 |
200 | /**
201 | * Next
202 | *
203 | * Move forward to the next row in the result set.
204 | */
205 | function next()
206 | {
207 | $this->fetch();
208 | }
209 |
210 | /**
211 | * Valid
212 | *
213 | * Determines if the current row is valid.
214 | *
215 | * @return boolean
216 | */
217 | function valid()
218 | {
219 | if ($this->row === false) return false;
220 | else return true;
221 | }
222 | }
223 | ?>
224 |
--------------------------------------------------------------------------------