http://justinvincent.com
官网,一切尽在里面的下载帮助文件中,妙哉也!!
ez_sql_core.php
1 <?php 2 3 /********************************************************************** 4 * Author: Justin Vincent (jv@vip.ie) 5 * Web...: http://justinvincent.com 6 * Name..: ezSQL 7 * Desc..: ezSQL Core module - database abstraction library to make 8 * it very easy to deal with databases. ezSQLcore can not be used by 9 * itself (it is designed for use by database specific modules). 10 * 11 */ 12 13 /********************************************************************** 14 * ezSQL Constants 15 */ 16 17 define('EZSQL_VERSION','2.17'); 18 define('OBJECT','OBJECT',true); 19 define('ARRAY_A','ARRAY_A',true); 20 define('ARRAY_N','ARRAY_N',true); 21 22 /********************************************************************** 23 * Core class containg common functions to manipulate query result 24 * sets once returned 25 */ 26 27 class ezSQLcore 28 { 29 30 var $trace = false; // same as $debug_all 31 var $debug_all = false; // same as $trace 32 var $debug_called = false; 33 var $vardump_called = false; 34 var $show_errors = true; 35 var $num_queries = 0; 36 var $last_query = null; 37 var $last_error = null; 38 var $col_info = null; 39 var $captured_errors = array(); 40 var $cache_dir = false; 41 var $cache_queries = false; 42 var $cache_inserts = false; 43 var $use_disk_cache = false; 44 var $cache_timeout = 24; // hours 45 var $timers = array(); 46 var $total_query_time = 0; 47 var $db_connect_time = 0; 48 var $trace_log = array(); 49 var $use_trace_log = false; 50 var $sql_log_file = false; 51 var $do_profile = false; 52 var $profile_times = array(); 53 54 // == TJH == default now needed for echo of debug function 55 var $debug_echo_is_on = true; 56 57 /********************************************************************** 58 * Constructor 59 */ 60 61 function ezSQLcore() 62 { 63 } 64 65 /********************************************************************** 66 * Get host and port from an "host:port" notation. 67 * Returns array of host and port. If port is omitted, returns $default 68 */ 69 70 function get_host_port( $host, $default = false ) 71 { 72 $port = $default; 73 if ( false !== strpos( $host, ':' ) ) { 74 list( $host, $port ) = explode( ':', $host ); 75 $port = (int) $port; 76 } 77 return array( $host, $port ); 78 } 79 80 /********************************************************************** 81 * Print SQL/DB error - over-ridden by specific DB class 82 */ 83 84 function register_error($err_str) 85 { 86 // Keep track of last error 87 $this->last_error = $err_str; 88 89 // Capture all errors to an error array no matter what happens 90 $this->captured_errors[] = array 91 ( 92 'error_str' => $err_str, 93 'query' => $this->last_query 94 ); 95 } 96 97 /********************************************************************** 98 * Turn error handling on or off.. 99 */ 100 101 function show_errors() 102 { 103 $this->show_errors = true; 104 } 105 106 function hide_errors() 107 { 108 $this->show_errors = false; 109 } 110 111 /********************************************************************** 112 * Kill cached query results 113 */ 114 115 function flush() 116 { 117 // Get rid of these 118 $this->last_result = null; 119 $this->col_info = null; 120 $this->last_query = null; 121 $this->from_disk_cache = false; 122 } 123 124 /********************************************************************** 125 * Get one variable from the DB - see docs for more detail 126 */ 127 128 function get_var($query=null,$x=0,$y=0) 129 { 130 131 // Log how the function was called 132 $this->func_call = "$db->get_var("$query",$x,$y)"; 133 134 // If there is a query then perform it if not then use cached results.. 135 if ( $query ) 136 { 137 $this->query($query); 138 } 139 140 // Extract var out of cached results based x,y vals 141 if ( $this->last_result[$y] ) 142 { 143 $values = array_values(get_object_vars($this->last_result[$y])); 144 } 145 146 // If there is a value return it else return null 147 return (isset($values[$x]) && $values[$x]!=='')?$values[$x]:null; 148 } 149 150 /********************************************************************** 151 * Get one row from the DB - see docs for more detail 152 */ 153 154 function get_row($query=null,$output=OBJECT,$y=0) 155 { 156 157 // Log how the function was called 158 $this->func_call = "$db->get_row("$query",$output,$y)"; 159 160 // If there is a query then perform it if not then use cached results.. 161 if ( $query ) 162 { 163 $this->query($query); 164 } 165 166 // If the output is an object then return object using the row offset.. 167 if ( $output == OBJECT ) 168 { 169 return $this->last_result[$y]?$this->last_result[$y]:null; 170 } 171 // If the output is an associative array then return row as such.. 172 elseif ( $output == ARRAY_A ) 173 { 174 return $this->last_result[$y]?get_object_vars($this->last_result[$y]):null; 175 } 176 // If the output is an numerical array then return row as such.. 177 elseif ( $output == ARRAY_N ) 178 { 179 return $this->last_result[$y]?array_values(get_object_vars($this->last_result[$y])):null; 180 } 181 // If invalid output type was specified.. 182 else 183 { 184 $this->show_errors ? trigger_error(" $db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N",E_USER_WARNING) : null; 185 } 186 187 } 188 189 /********************************************************************** 190 * Function to get 1 column from the cached result set based in X index 191 * see docs for usage and info 192 */ 193 194 function get_col($query=null,$x=0) 195 { 196 197 $new_array = array(); 198 199 // If there is a query then perform it if not then use cached results.. 200 if ( $query ) 201 { 202 $this->query($query); 203 } 204 205 // Extract the column values 206 for ( $i=0; $i < count($this->last_result); $i++ ) 207 { 208 $new_array[$i] = $this->get_var(null,$x,$i); 209 } 210 211 return $new_array; 212 } 213 214 215 /********************************************************************** 216 * Return the the query as a result set - see docs for more details 217 */ 218 219 function get_results($query=null, $output = OBJECT) 220 { 221 222 // Log how the function was called 223 $this->func_call = "$db->get_results("$query", $output)"; 224 225 // If there is a query then perform it if not then use cached results.. 226 if ( $query ) 227 { 228 $this->query($query); 229 } 230 231 // Send back array of objects. Each row is an object 232 if ( $output == OBJECT ) 233 { 234 return $this->last_result; 235 } 236 elseif ( $output == ARRAY_A || $output == ARRAY_N ) 237 { 238 if ( $this->last_result ) 239 { 240 $i=0; 241 foreach( $this->last_result as $row ) 242 { 243 244 $new_array[$i] = get_object_vars($row); 245 246 if ( $output == ARRAY_N ) 247 { 248 $new_array[$i] = array_values($new_array[$i]); 249 } 250 251 $i++; 252 } 253 254 return $new_array; 255 } 256 else 257 { 258 return array(); 259 } 260 } 261 } 262 263 264 /********************************************************************** 265 * Function to get column meta data info pertaining to the last query 266 * see docs for more info and usage 267 */ 268 269 function get_col_info($info_type="name",$col_offset=-1) 270 { 271 272 if ( $this->col_info ) 273 { 274 if ( $col_offset == -1 ) 275 { 276 $i=0; 277 foreach($this->col_info as $col ) 278 { 279 $new_array[$i] = $col->{$info_type}; 280 $i++; 281 } 282 return $new_array; 283 } 284 else 285 { 286 return $this->col_info[$col_offset]->{$info_type}; 287 } 288 289 } 290 291 } 292 293 /********************************************************************** 294 * store_cache 295 */ 296 297 function store_cache($query,$is_insert) 298 { 299 300 // The would be cache file for this query 301 $cache_file = $this->cache_dir.'/'.md5($query); 302 303 // disk caching of queries 304 if ( $this->use_disk_cache && ( $this->cache_queries && ! $is_insert ) || ( $this->cache_inserts && $is_insert )) 305 { 306 if ( ! is_dir($this->cache_dir) ) 307 { 308 $this->register_error("Could not open cache dir: $this->cache_dir"); 309 $this->show_errors ? trigger_error("Could not open cache dir: $this->cache_dir",E_USER_WARNING) : null; 310 } 311 else 312 { 313 // Cache all result values 314 $result_cache = array 315 ( 316 'col_info' => $this->col_info, 317 'last_result' => $this->last_result, 318 'num_rows' => $this->num_rows, 319 'return_value' => $this->num_rows, 320 ); 321 file_put_contents($cache_file, serialize($result_cache)); 322 if( file_exists($cache_file . ".updating") ) 323 unlink($cache_file . ".updating"); 324 } 325 } 326 327 } 328 329 /********************************************************************** 330 * get_cache 331 */ 332 333 function get_cache($query) 334 { 335 336 // The would be cache file for this query 337 $cache_file = $this->cache_dir.'/'.md5($query); 338 339 // Try to get previously cached version 340 if ( $this->use_disk_cache && file_exists($cache_file) ) 341 { 342 // Only use this cache file if less than 'cache_timeout' (hours) 343 if ( (time() - filemtime($cache_file)) > ($this->cache_timeout*3600) && 344 !(file_exists($cache_file . ".updating") && (time() - filemtime($cache_file . ".updating") < 60)) ) 345 { 346 touch($cache_file . ".updating"); // Show that we in the process of updating the cache 347 } 348 else 349 { 350 $result_cache = unserialize(file_get_contents($cache_file)); 351 352 $this->col_info = $result_cache['col_info']; 353 $this->last_result = $result_cache['last_result']; 354 $this->num_rows = $result_cache['num_rows']; 355 356 $this->from_disk_cache = true; 357 358 // If debug ALL queries 359 $this->trace || $this->debug_all ? $this->debug() : null ; 360 361 return $result_cache['return_value']; 362 } 363 } 364 365 } 366 367 /********************************************************************** 368 * Dumps the contents of any input variable to screen in a nicely 369 * formatted and easy to understand way - any type: Object, Var or Array 370 */ 371 372 function vardump($mixed='') 373 { 374 375 // Start outup buffering 376 ob_start(); 377 378 echo "<p><table><tr><td bgcolor=ffffff><blockquote><font color=000090>"; 379 echo "<pre><font face=arial>"; 380 381 if ( ! $this->vardump_called ) 382 { 383 echo "<font color=800080><b>ezSQL</b> (v".EZSQL_VERSION.") <b>Variable Dump..</b></font> "; 384 } 385 386 $var_type = gettype ($mixed); 387 print_r(($mixed?$mixed:"<font color=red>No Value / False</font>")); 388 echo " <b>Type:</b> " . ucfirst($var_type) . " "; 389 echo "<b>Last Query</b> [$this->num_queries]<b>:</b> ".($this->last_query?$this->last_query:"NULL")." "; 390 echo "<b>Last Function Call:</b> " . ($this->func_call?$this->func_call:"None")." "; 391 echo "<b>Last Rows Returned:</b> ".count($this->last_result)." "; 392 echo "</font></pre></font></blockquote></td></tr></table>".$this->donation(); 393 echo " <hr size=1 noshade color=dddddd>"; 394 395 // Stop output buffering and capture debug HTML 396 $html = ob_get_contents(); 397 ob_end_clean(); 398 399 // Only echo output if it is turned on 400 if ( $this->debug_echo_is_on ) 401 { 402 echo $html; 403 } 404 405 $this->vardump_called = true; 406 407 return $html; 408 409 } 410 411 /********************************************************************** 412 * Alias for the above function 413 */ 414 415 function dumpvar($mixed) 416 { 417 $this->vardump($mixed); 418 } 419 420 /********************************************************************** 421 * Displays the last query string that was sent to the database & a 422 * table listing results (if there were any). 423 * (abstracted into a seperate file to save server overhead). 424 */ 425 426 function debug($print_to_screen=true) 427 { 428 429 // Start outup buffering 430 ob_start(); 431 432 echo "<blockquote>"; 433 434 // Only show ezSQL credits once.. 435 if ( ! $this->debug_called ) 436 { 437 echo "<font color=800080 face=arial size=2><b>ezSQL</b> (v".EZSQL_VERSION.") <b>Debug..</b></font><p> "; 438 } 439 440 if ( $this->last_error ) 441 { 442 echo "<font face=arial size=2 color=000099><b>Last Error --</b> [<font color=000000><b>$this->last_error</b></font>]<p>"; 443 } 444 445 if ( $this->from_disk_cache ) 446 { 447 echo "<font face=arial size=2 color=000099><b>Results retrieved from disk cache</b></font><p>"; 448 } 449 450 echo "<font face=arial size=2 color=000099><b>Query</b> [$this->num_queries] <b>--</b> "; 451 echo "[<font color=000000><b>$this->last_query</b></font>]</font><p>"; 452 453 echo "<font face=arial size=2 color=000099><b>Query Result..</b></font>"; 454 echo "<blockquote>"; 455 456 if ( $this->col_info ) 457 { 458 459 // ===================================================== 460 // Results top rows 461 462 echo "<table cellpadding=5 cellspacing=1 bgcolor=555555>"; 463 echo "<tr bgcolor=eeeeee><td nowrap valign=bottom><font color=555599 face=arial size=2><b>(row)</b></font></td>"; 464 465 466 for ( $i=0; $i < count($this->col_info); $i++ ) 467 { 468 /* when selecting count(*) the maxlengh is not set, size is set instead. */ 469 echo "<td nowrap align=left valign=top><font size=1 color=555599 face=arial>{$this->col_info[$i]->type}"; 470 if (!isset($this->col_info[$i]->max_length)) 471 { 472 echo "{$this->col_info[$i]->size}"; 473 } else { 474 echo "{$this->col_info[$i]->max_length}"; 475 } 476 echo "</font><br><span style='font-family: arial; font-size: 10pt; font-weight: bold;'>{$this->col_info[$i]->name}</span></td>"; 477 } 478 479 echo "</tr>"; 480 481 // ====================================================== 482 // print main results 483 484 if ( $this->last_result ) 485 { 486 487 $i=0; 488 foreach ( $this->get_results(null,ARRAY_N) as $one_row ) 489 { 490 $i++; 491 echo "<tr bgcolor=ffffff><td bgcolor=eeeeee nowrap align=middle><font size=2 color=555599 face=arial>$i</font></td>"; 492 493 foreach ( $one_row as $item ) 494 { 495 echo "<td nowrap><font face=arial size=2>$item</font></td>"; 496 } 497 498 echo "</tr>"; 499 } 500 501 } // if last result 502 else 503 { 504 echo "<tr bgcolor=ffffff><td colspan=".(count($this->col_info)+1)."><font face=arial size=2>No Results</font></td></tr>"; 505 } 506 507 echo "</table>"; 508 509 } // if col_info 510 else 511 { 512 echo "<font face=arial size=2>No Results</font>"; 513 } 514 515 echo "</blockquote></blockquote>".$this->donation()."<hr noshade color=dddddd size=1>"; 516 517 // Stop output buffering and capture debug HTML 518 $html = ob_get_contents(); 519 ob_end_clean(); 520 521 // Only echo output if it is turned on 522 if ( $this->debug_echo_is_on && $print_to_screen) 523 { 524 echo $html; 525 } 526 527 $this->debug_called = true; 528 529 return $html; 530 531 } 532 533 /********************************************************************** 534 * Naughty little function to ask for some remuniration! 535 */ 536 537 function donation() 538 { 539 return "<font size=1 face=arial color=000000>If ezSQL has helped <a href="https://www.paypal.com/xclick/business=justin%40justinvincent.com&item_name=ezSQL&no_note=1&tax=0" style="color: 0000CC;">make a donation!?</a> <!--[ go on! you know you want to! ]--></font>"; 540 } 541 542 /********************************************************************** 543 * Timer related functions 544 */ 545 546 function timer_get_cur() 547 { 548 list($usec, $sec) = explode(" ",microtime()); 549 return ((float)$usec + (float)$sec); 550 } 551 552 function timer_start($timer_name) 553 { 554 $this->timers[$timer_name] = $this->timer_get_cur(); 555 } 556 557 function timer_elapsed($timer_name) 558 { 559 return round($this->timer_get_cur() - $this->timers[$timer_name],2); 560 } 561 562 function timer_update_global($timer_name) 563 { 564 if ( $this->do_profile ) 565 { 566 $this->profile_times[] = array 567 ( 568 'query' => $this->last_query, 569 'time' => $this->timer_elapsed($timer_name) 570 ); 571 } 572 573 $this->total_query_time += $this->timer_elapsed($timer_name); 574 } 575 576 /********************************************************************** 577 * Creates a SET nvp sql string from an associative array (and escapes all values) 578 * 579 * Usage: 580 * 581 * $db_data = array('login'=>'jv','email'=>'jv@vip.ie', 'user_id' => 1, 'created' => 'NOW()'); 582 * 583 * $db->query("INSERT INTO users SET ".$db->get_set($db_data)); 584 * 585 * ...OR... 586 * 587 * $db->query("UPDATE users SET ".$db->get_set($db_data)." WHERE user_id = 1"); 588 * 589 * Output: 590 * 591 * login = 'jv', email = 'jv@vip.ie', user_id = 1, created = NOW() 592 */ 593 594 function get_set($params) 595 { 596 if( !is_array( $params ) ) 597 { 598 $this->register_error( 'get_set() parameter invalid. Expected array in '.__FILE__.' on line '.__LINE__); 599 return; 600 } 601 $sql = array(); 602 foreach ( $params as $field => $val ) 603 { 604 if ( $val === 'true' || $val === true ) 605 $val = 1; 606 if ( $val === 'false' || $val === false ) 607 $val = 0; 608 609 switch( $val ){ 610 case 'NOW()' : 611 case 'NULL' : 612 $sql[] = "$field = $val"; 613 break; 614 default : 615 $sql[] = "$field = '".$this->escape( $val )."'"; 616 } 617 } 618 619 return implode( ', ' , $sql ); 620 } 621 622 }
//ez_sql_mysql.php
1 <?php 2 3 /********************************************************************** 4 * Author: Justin Vincent (jv@jvmultimedia.com) 5 * Web...: http://twitter.com/justinvincent 6 * Name..: ezSQL_mysql 7 * Desc..: mySQL component (part of ezSQL databse abstraction library) 8 * 9 */ 10 11 /********************************************************************** 12 * ezSQL error strings - mySQL 13 */ 14 15 global $ezsql_mysql_str; 16 17 $ezsql_mysql_str = array 18 ( 19 1 => 'Require $dbuser and $dbpassword to connect to a database server', 20 2 => 'Error establishing mySQL database connection. Correct user/password? Correct hostname? Database server running?', 21 3 => 'Require $dbname to select a database', 22 4 => 'mySQL database connection is not active', 23 5 => 'Unexpected error while trying to select database' 24 ); 25 26 /********************************************************************** 27 * ezSQL Database specific class - mySQL 28 */ 29 30 if ( ! function_exists ('mysql_connect') ) die('<b>Fatal Error:</b> ezSQL_mysql requires mySQL Lib to be compiled and or linked in to the PHP engine'); 31 if ( ! class_exists ('ezSQLcore') ) die('<b>Fatal Error:</b> ezSQL_mysql requires ezSQLcore (ez_sql_core.php) to be included/loaded before it can be used'); 32 33 class ezSQL_mysql extends ezSQLcore 34 { 35 36 var $dbuser = false; 37 var $dbpassword = false; 38 var $dbname = false; 39 var $dbhost = false; 40 var $encoding = false; 41 var $rows_affected = false; 42 43 /********************************************************************** 44 * Constructor - allow the user to perform a quick connect at the 45 * same time as initialising the ezSQL_mysql class 46 */ 47 48 function ezSQL_mysql($dbuser='', $dbpassword='', $dbname='', $dbhost='localhost', $encoding='') 49 { 50 $this->dbuser = $dbuser; 51 $this->dbpassword = $dbpassword; 52 $this->dbname = $dbname; 53 $this->dbhost = $dbhost; 54 $this->encoding = $encoding; 55 } 56 57 /********************************************************************** 58 * Short hand way to connect to mySQL database server 59 * and select a mySQL database at the same time 60 */ 61 62 function quick_connect($dbuser='', $dbpassword='', $dbname='', $dbhost='localhost', $encoding='') 63 { 64 $return_val = false; 65 if ( ! $this->connect($dbuser, $dbpassword, $dbhost,true) ) ; 66 else if ( ! $this->select($dbname,$encoding) ) ; 67 else $return_val = true; 68 return $return_val; 69 } 70 71 /********************************************************************** 72 * Try to connect to mySQL database server 73 */ 74 75 function connect($dbuser='', $dbpassword='', $dbhost='localhost') 76 { 77 global $ezsql_mysql_str; $return_val = false; 78 79 // Keep track of how long the DB takes to connect 80 $this->timer_start('db_connect_time'); 81 82 // Must have a user and a password 83 if ( ! $dbuser ) 84 { 85 $this->register_error($ezsql_mysql_str[1].' in '.__FILE__.' on line '.__LINE__); 86 $this->show_errors ? trigger_error($ezsql_mysql_str[1],E_USER_WARNING) : null; 87 } 88 // Try to establish the server database handle 89 else if ( ! $this->dbh = @mysql_connect($dbhost,$dbuser,$dbpassword,true,131074) ) 90 { 91 $this->register_error($ezsql_mysql_str[2].' in '.__FILE__.' on line '.__LINE__); 92 $this->show_errors ? trigger_error($ezsql_mysql_str[2],E_USER_WARNING) : null; 93 } 94 else 95 { 96 $this->dbuser = $dbuser; 97 $this->dbpassword = $dbpassword; 98 $this->dbhost = $dbhost; 99 $return_val = true; 100 } 101 102 return $return_val; 103 } 104 105 /********************************************************************** 106 * Try to select a mySQL database 107 */ 108 109 function select($dbname='', $encoding='') 110 { 111 global $ezsql_mysql_str; $return_val = false; 112 113 // Must have a database name 114 if ( ! $dbname ) 115 { 116 $this->register_error($ezsql_mysql_str[3].' in '.__FILE__.' on line '.__LINE__); 117 $this->show_errors ? trigger_error($ezsql_mysql_str[3],E_USER_WARNING) : null; 118 } 119 120 // Must have an active database connection 121 else if ( ! $this->dbh ) 122 { 123 $this->register_error($ezsql_mysql_str[4].' in '.__FILE__.' on line '.__LINE__); 124 $this->show_errors ? trigger_error($ezsql_mysql_str[4],E_USER_WARNING) : null; 125 } 126 127 // Try to connect to the database 128 else if ( !@mysql_select_db($dbname,$this->dbh) ) 129 { 130 // Try to get error supplied by mysql if not use our own 131 if ( !$str = @mysql_error($this->dbh)) 132 $str = $ezsql_mysql_str[5]; 133 134 $this->register_error($str.' in '.__FILE__.' on line '.__LINE__); 135 $this->show_errors ? trigger_error($str,E_USER_WARNING) : null; 136 } 137 else 138 { 139 $this->dbname = $dbname; 140 if ( $encoding == '') $encoding = $this->encoding; 141 if($encoding!='') 142 { 143 $encoding = strtolower(str_replace("-","",$encoding)); 144 $charsets = array(); 145 $result = mysql_query("SHOW CHARACTER SET"); 146 while($row = mysql_fetch_array($result,MYSQL_ASSOC)) 147 { 148 $charsets[] = $row["Charset"]; 149 } 150 if(in_array($encoding,$charsets)){ 151 mysql_query("SET NAMES '".$encoding."'"); 152 } 153 } 154 155 $return_val = true; 156 } 157 158 return $return_val; 159 } 160 161 /********************************************************************** 162 * Format a mySQL string correctly for safe mySQL insert 163 * (no mater if magic quotes are on or not) 164 */ 165 166 function escape($str) 167 { 168 // If there is no existing database connection then try to connect 169 if ( ! isset($this->dbh) || ! $this->dbh ) 170 { 171 $this->connect($this->dbuser, $this->dbpassword, $this->dbhost); 172 $this->select($this->dbname, $this->encoding); 173 } 174 175 return mysql_real_escape_string(stripslashes($str)); 176 } 177 178 /********************************************************************** 179 * Return mySQL specific system date syntax 180 * i.e. Oracle: SYSDATE Mysql: NOW() 181 */ 182 183 function sysdate() 184 { 185 return 'NOW()'; 186 } 187 188 /********************************************************************** 189 * Perform mySQL query and try to detirmin result value 190 */ 191 192 function query($query) 193 { 194 195 // This keeps the connection alive for very long running scripts 196 if ( $this->num_queries >= 500 ) 197 { 198 $this->num_queries = 0; 199 $this->disconnect(); 200 $this->quick_connect($this->dbuser,$this->dbpassword,$this->dbname,$this->dbhost,$this->encoding); 201 } 202 203 // Initialise return 204 $return_val = 0; 205 206 // Flush cached values.. 207 $this->flush(); 208 209 // For reg expressions 210 $query = trim($query); 211 212 // Log how the function was called 213 $this->func_call = "$db->query("$query")"; 214 215 // Keep track of the last query for debug.. 216 $this->last_query = $query; 217 218 // Count how many queries there have been 219 $this->num_queries++; 220 221 // Start timer 222 $this->timer_start($this->num_queries); 223 224 // Use core file cache function 225 if ( $cache = $this->get_cache($query) ) 226 { 227 // Keep tack of how long all queries have taken 228 $this->timer_update_global($this->num_queries); 229 230 // Trace all queries 231 if ( $this->use_trace_log ) 232 { 233 $this->trace_log[] = $this->debug(false); 234 } 235 236 return $cache; 237 } 238 239 // If there is no existing database connection then try to connect 240 if ( ! isset($this->dbh) || ! $this->dbh ) 241 { 242 $this->connect($this->dbuser, $this->dbpassword, $this->dbhost); 243 $this->select($this->dbname,$this->encoding); 244 // No existing connection at this point means the server is unreachable 245 if ( ! isset($this->dbh) || ! $this->dbh ) 246 return false; 247 } 248 249 // Perform the query via std mysql_query function.. 250 $this->result = @mysql_query($query,$this->dbh); 251 252 // If there is an error then take note of it.. 253 if ( $str = @mysql_error($this->dbh) ) 254 { 255 $this->register_error($str); 256 $this->show_errors ? trigger_error($str,E_USER_WARNING) : null; 257 return false; 258 } 259 260 // Query was an insert, delete, update, replace 261 if ( preg_match("/^(insert|delete|update|replace|truncate|drop|create|alter|set|lock|unlock)s+/i",$query) ) 262 { 263 $is_insert = true; 264 $this->rows_affected = @mysql_affected_rows($this->dbh); 265 266 // Take note of the insert_id 267 if ( preg_match("/^(insert|replace)s+/i",$query) ) 268 { 269 $this->insert_id = @mysql_insert_id($this->dbh); 270 } 271 272 // Return number fo rows affected 273 $return_val = $this->rows_affected; 274 } 275 // Query was a select 276 else 277 { 278 $is_insert = false; 279 280 // Take note of column info 281 $i=0; 282 while ($i < @mysql_num_fields($this->result)) 283 { 284 $this->col_info[$i] = @mysql_fetch_field($this->result); 285 $i++; 286 } 287 288 // Store Query Results 289 $num_rows=0; 290 while ( $row = @mysql_fetch_object($this->result) ) 291 { 292 // Store relults as an objects within main array 293 $this->last_result[$num_rows] = $row; 294 $num_rows++; 295 } 296 297 @mysql_free_result($this->result); 298 299 // Log number of rows the query returned 300 $this->num_rows = $num_rows; 301 302 // Return number of rows selected 303 $return_val = $this->num_rows; 304 } 305 306 // disk caching of queries 307 $this->store_cache($query,$is_insert); 308 309 // If debug ALL queries 310 $this->trace || $this->debug_all ? $this->debug() : null ; 311 312 // Keep tack of how long all queries have taken 313 $this->timer_update_global($this->num_queries); 314 315 // Trace all queries 316 if ( $this->use_trace_log ) 317 { 318 $this->trace_log[] = $this->debug(false); 319 } 320 321 return $return_val; 322 323 } 324 325 /********************************************************************** 326 * Close the active mySQL connection 327 */ 328 329 function disconnect() 330 { 331 @mysql_close($this->dbh); 332 } 333 334 } 335
//disk_cache_example.php
1 <?php 2 3 // Standard ezSQL Libs 4 include_once "../shared/ez_sql_core.php"; 5 include_once "ez_sql_mysql.php"; 6 7 // Initialise singleton 8 $db = new ezSQL_mysql('db_user', 'db_pass', 'db_name'); 9 10 // Cache expiry 11 $db->cache_timeout = 24; // Note: this is hours 12 13 // Specify a cache dir. Path is taken from calling script 14 $db->cache_dir = 'ezsql_cache'; 15 16 // (1. You must create this dir. first!) 17 // (2. Might need to do chmod 775) 18 19 // Global override setting to turn disc caching off 20 // (but not on) 21 $db->use_disk_cache = true; 22 23 // By wrapping up queries you can ensure that the default 24 // is NOT to cache unless specified 25 $db->cache_queries = true; 26 27 // At last.. a query! 28 $db->get_results("SHOW TABLES"); 29 $db->debug(); 30 31 // Select * from use 32 $db->get_results("SELECT * FROM User"); 33 $db->debug(); 34 35 // This ensures only the above querys are cached 36 $db->cache_queries = false; 37 38 // This query is NOT cached 39 $db->get_results("SELECT * FROM User LIMIT 0,1"); 40 $db->debug(); 41 42 /* 43 44 Of course, if you want to cache EVERYTHING just do.. 45 46 $db = new ezSQL_mysql('db_user', 'db_pass', 'db_name'); 47 $db->use_disk_cache = true; 48 $db->cache_queries = true; 49 $db->cache_timeout = 24; 50 51 */ 52 53 ?>
//ez_sql_core_202console.php
1 <?php 2 // ================================================================= 3 // == TJH == To provide optional return value as opposed to simple echo 4 // == TJH == of the $db->vardump and $db->debug functions 5 6 // == TJH == Helpful for assigning the output to a var for handling in situations like template 7 // == TJH == engines where you want the debugging output rendered in a particular location. 8 9 // == TJH == This latest version 0.2 alpha includes a modification that allows 10 // == TJH == the original dump and debug behaviours to be maintained by default 11 // == TJH == and hopefully be backward compatible with previous ezSQL versions 12 13 // == TJH == USAGE: $ezdump = print_r($db->vardump($result),true); 14 // == TJH == USAGE: $ezconsole = print_r($db->console,true); 15 // ================================================================= 16 17 /********************************************************************** 18 * Author: Justin Vincent (jv@jvmultimedia.com) 19 * Web...: http://twitter.com/justinvincent 20 * Name..: ezSQL 21 * Desc..: ezSQL Core module - database abstraction library to make 22 * it very easy to deal with databases. 23 * 24 */ 25 26 /********************************************************************** 27 * ezSQL Constants 28 */ 29 30 define('EZSQL_VERSION','2.02-console'); 31 define('OBJECT','OBJECT',true); 32 define('ARRAY_A','ARRAY_A',true); 33 define('ARRAY_N','ARRAY_N',true); 34 define('EZSQL_CORE_ERROR','ezSQLcore can not be used by itself (it is designed for use by database specific modules).'); 35 36 37 /********************************************************************** 38 * Core class containg common functions to manipulate query result 39 * sets once returned 40 */ 41 42 class ezSQLcore 43 { 44 45 var $trace = false; // same as $debug_all 46 var $debug_all = false; // same as $trace 47 // === TJH === 48 var $debug_echo = true; // == TJH == // default now needed for echo of debug function 49 var $debug_called = false; 50 var $vardump_called = false; 51 var $show_errors = true; 52 var $num_queries = 0; 53 var $last_query = null; 54 var $last_error = null; 55 var $col_info = null; 56 var $captured_errors = array(); 57 var $cache_dir = false; 58 var $cache_queries = false; 59 var $cache_inserts = false; 60 var $use_disk_cache = false; 61 var $cache_timeout = 24; // hours 62 63 /********************************************************************** 64 * Constructor 65 */ 66 67 function ezSQLcore() 68 { 69 } 70 71 /********************************************************************** 72 * Connect to DB - over-ridden by specific DB class 73 */ 74 75 function connect() 76 { 77 die(EZSQL_CORE_ERROR); 78 } 79 80 /********************************************************************** 81 * Select DB - over-ridden by specific DB class 82 */ 83 84 function select() 85 { 86 die(EZSQL_CORE_ERROR); 87 } 88 89 /********************************************************************** 90 * Basic Query - over-ridden by specific DB class 91 */ 92 93 function query() 94 { 95 die(EZSQL_CORE_ERROR); 96 } 97 98 /********************************************************************** 99 * Format a string correctly for safe insert - over-ridden by specific 100 * DB class 101 */ 102 103 function escape() 104 { 105 die(EZSQL_CORE_ERROR); 106 } 107 108 /********************************************************************** 109 * Return database specific system date syntax 110 * i.e. Oracle: SYSDATE Mysql: NOW() 111 */ 112 113 function sysdate() 114 { 115 die(EZSQL_CORE_ERROR); 116 } 117 118 /********************************************************************** 119 * Print SQL/DB error - over-ridden by specific DB class 120 */ 121 122 function register_error($err_str) 123 { 124 // Keep track of last error 125 $this->last_error = $err_str; 126 127 // Capture all errors to an error array no matter what happens 128 $this->captured_errors[] = array 129 ( 130 'error_str' => $err_str, 131 'query' => $this->last_query 132 ); 133 } 134 135 /********************************************************************** 136 * Turn error handling on or off.. 137 */ 138 139 function show_errors() 140 { 141 $this->show_errors = true; 142 } 143 144 function hide_errors() 145 { 146 $this->show_errors = false; 147 } 148 149 /********************************************************************** 150 * Kill cached query results 151 */ 152 153 function flush() 154 { 155 // Get rid of these 156 $this->last_result = null; 157 $this->col_info = null; 158 $this->last_query = null; 159 $this->from_disk_cache = false; 160 } 161 162 /********************************************************************** 163 * Get one variable from the DB - see docs for more detail 164 */ 165 166 function get_var($query=null,$x=0,$y=0) 167 { 168 169 // Log how the function was called 170 $this->func_call = "$db->get_var("$query",$x,$y)"; 171 172 // If there is a query then perform it if not then use cached results.. 173 if ( $query ) 174 { 175 $this->query($query); 176 } 177 178 // Extract var out of cached results based x,y vals 179 if ( $this->last_result[$y] ) 180 { 181 $values = array_values(get_object_vars($this->last_result[$y])); 182 } 183 184 // If there is a value return it else return null 185 return (isset($values[$x]) && $values[$x]!=='')?$values[$x]:null; 186 } 187 188 /********************************************************************** 189 * Get one row from the DB - see docs for more detail 190 */ 191 192 function get_row($query=null,$output=OBJECT,$y=0) 193 { 194 195 // Log how the function was called 196 $this->func_call = "$db->get_row("$query",$output,$y)"; 197 198 // If there is a query then perform it if not then use cached results.. 199 if ( $query ) 200 { 201 $this->query($query); 202 } 203 204 // If the output is an object then return object using the row offset.. 205 if ( $output == OBJECT ) 206 { 207 return $this->last_result[$y]?$this->last_result[$y]:null; 208 } 209 // If the output is an associative array then return row as such.. 210 elseif ( $output == ARRAY_A ) 211 { 212 return $this->last_result[$y]?get_object_vars($this->last_result[$y]):null; 213 } 214 // If the output is an numerical array then return row as such.. 215 elseif ( $output == ARRAY_N ) 216 { 217 return $this->last_result[$y]?array_values(get_object_vars($this->last_result[$y])):null; 218 } 219 // If invalid output type was specified.. 220 else 221 { 222 $this->print_error(" $db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N"); 223 } 224 225 } 226 227 /********************************************************************** 228 * Function to get 1 column from the cached result set based in X index 229 * see docs for usage and info 230 */ 231 232 function get_col($query=null,$x=0) 233 { 234 235 // If there is a query then perform it if not then use cached results.. 236 if ( $query ) 237 { 238 $this->query($query); 239 } 240 241 // Extract the column values 242 for ( $i=0; $i < count($this->last_result); $i++ ) 243 { 244 $new_array[$i] = $this->get_var(null,$x,$i); 245 } 246 247 return $new_array; 248 } 249 250 251 /********************************************************************** 252 * Return the the query as a result set - see docs for more details 253 */ 254 255 function get_results($query=null, $output = OBJECT) 256 { 257 258 // Log how the function was called 259 $this->func_call = "$db->get_results("$query", $output)"; 260 261 // If there is a query then perform it if not then use cached results.. 262 if ( $query ) 263 { 264 $this->query($query); 265 } 266 267 // Send back array of objects. Each row is an object 268 if ( $output == OBJECT ) 269 { 270 return $this->last_result; 271 } 272 elseif ( $output == ARRAY_A || $output == ARRAY_N ) 273 { 274 if ( $this->last_result ) 275 { 276 $i=0; 277 foreach( $this->last_result as $row ) 278 { 279 280 $new_array[$i] = get_object_vars($row); 281 282 if ( $output == ARRAY_N ) 283 { 284 $new_array[$i] = array_values($new_array[$i]); 285 } 286 287 $i++; 288 } 289 290 return $new_array; 291 } 292 else 293 { 294 return array(); 295 } 296 } 297 } 298 299 300 /********************************************************************** 301 * Function to get column meta data info pertaining to the last query 302 * see docs for more info and usage 303 */ 304 305 function get_col_info($info_type="name",$col_offset=-1) 306 { 307 308 if ( $this->col_info ) 309 { 310 if ( $col_offset == -1 ) 311 { 312 $i=0; 313 foreach($this->col_info as $col ) 314 { 315 $new_array[$i] = $col->{$info_type}; 316 $i++; 317 } 318 return $new_array; 319 } 320 else 321 { 322 return $this->col_info[$col_offset]->{$info_type}; 323 } 324 325 } 326 327 } 328 329 /********************************************************************** 330 * store_cache 331 */ 332 333 function store_cache($query,$is_insert) 334 { 335 336 // The would be cache file for this query 337 $cache_file = $this->cache_dir.'/'.md5($query); 338 339 // disk caching of queries 340 if ( $this->use_disk_cache && ( $this->cache_queries && ! $is_insert ) || ( $this->cache_inserts && $is_insert )) 341 { 342 if ( ! is_dir($this->cache_dir) ) 343 { 344 $this->register_error("Could not open cache dir: $this->cache_dir"); 345 $this->show_errors ? trigger_error("Could not open cache dir: $this->cache_dir",E_USER_WARNING) : null; 346 } 347 else 348 { 349 // Cache all result values 350 $result_cache = array 351 ( 352 'col_info' => $this->col_info, 353 'last_result' => $this->last_result, 354 'num_rows' => $this->num_rows, 355 'return_value' => $this->num_rows, 356 ); 357 error_log ( serialize($result_cache), 3, $cache_file); 358 } 359 } 360 361 } 362 363 /********************************************************************** 364 * get_cache 365 */ 366 367 function get_cache($query) 368 { 369 370 // The would be cache file for this query 371 $cache_file = $this->cache_dir.'/'.md5($query); 372 373 // Try to get previously cached version 374 if ( $this->use_disk_cache && file_exists($cache_file) ) 375 { 376 // Only use this cache file if less than 'cache_timeout' (hours) 377 if ( (time() - filemtime($cache_file)) > ($this->cache_timeout*3600) ) 378 { 379 unlink($cache_file); 380 } 381 else 382 { 383 $result_cache = unserialize(file_get_contents($cache_file)); 384 385 $this->col_info = $result_cache['col_info']; 386 $this->last_result = $result_cache['last_result']; 387 $this->num_rows = $result_cache['num_rows']; 388 389 $this->from_disk_cache = true; 390 391 // If debug ALL queries 392 $this->trace || $this->debug_all ? $this->debug() : null ; 393 394 return $result_cache['return_value']; 395 } 396 } 397 398 } 399 400 /********************************************************************** 401 * Dumps the contents of any input variable to screen in a nicely 402 * formatted and easy to understand way - any type: Object, Var or Array 403 */ 404 405 // === TJH === This is hacked to OPTIONALLY generate a "$return_var" 406 // === TJH === must also set $db->debug_echo = false; in your script to override default behaviour 407 // === TJH === instead of a simple "echo" to the current screen (DEFAULT) 408 // === TJH === USAGE: $ezdebug = print_r($db->vardump($result),true); 409 410 function vardump($mixed='') 411 { 412 $return_var .= "<p><table><tr><td bgcolor=ffffff><blockquote><font color=000090>"; 413 $return_var .= "<pre><font face=arial>"; 414 415 if ( ! $this->vardump_called ) 416 { 417 $return_var .= "<font color=800080><b>ezSQL</b> (v".EZSQL_VERSION.") <b>Variable Dump..</b></font> "; 418 } 419 420 $var_type = gettype ($mixed); 421 $return_var .= print_r(($mixed?$mixed:"<font color=red>No Value / False</font>"),true); 422 $return_var .= " <b>Type:</b> " . ucfirst($var_type) . " "; 423 $return_var .= "<b>Last Query</b> [$this->num_queries]<b>:</b> ".($this->last_query?$this->last_query:"NULL")." "; 424 $return_var .= "<b>Last Function Call:</b> " . ($this->func_call?$this->func_call:"None")." "; 425 $return_var .= "<b>Last Rows Returned:</b> ".count($this->last_result)." "; 426 $return_var .= "</font></pre></font></blockquote></td></tr></table>".$this->donation(); 427 $return_var .= " <hr size=1 noshade color=dddddd>"; 428 429 $this->vardump_called = true; 430 if($this->debug_echo){ 431 echo $return_var; 432 } 433 434 return $return_var; 435 } 436 437 /********************************************************************** 438 * Alias for the above function 439 */ 440 441 function dumpvar($mixed) 442 { 443 $this->vardump($mixed); 444 } 445 446 /********************************************************************** 447 * Displays the last query string that was sent to the database & a 448 * table listing results (if there were any). 449 * (abstracted into a seperate file to save server overhead). 450 */ 451 452 // === TJH === The debug() function is now hacked to OPTIOANLLY create a return result 453 // === TJH === that can be called as a variable, just changed all "echo"s to "$this->console .= " 454 // === TJH === this is accessed with "$db->console" obviously 455 // === TJH === n.b. you must also set $db->debug_echo = false; to override default behaviour 456 457 function debug($debug_echo) // === TJH === set a default for function to be able to switch "echo" on/off 458 { 459 460 //$this->console .= "<blockquote>"; // === TJH == commented out to change output formatting slightly 461 // Only show ezSQL credits once.. 462 if ( ! $this->debug_called ) 463 { 464 $this->console .= "<font color=800080 face=arial size=2><b>ezSQL</b> (v".EZSQL_VERSION.") <b>Debug..</b></font><p> "; 465 } 466 467 if ( $this->last_error ) 468 { 469 $this->console .= "<font face=arial size=2 color=000099><b>Last Error --</b> [<font color=000000><b>$this->last_error</b></font>]<p>"; 470 } 471 472 if ( $this->from_disk_cache ) 473 { 474 $this->console .= "<font face=arial size=2 color=000099><b>Results retrieved from disk cache</b></font><p>"; 475 } 476 477 $this->console .= "<font face=arial size=2 color=000099><b>Query</b> [$this->num_queries] <b>--</b> "; 478 $this->console .= "[<font color=000000><b>$this->last_query</b></font>]</font><p>"; 479 480 $this->console .= "<font face=arial size=2 color=000099><b>Query Result..</b></font>"; 481 $this->console .= "<blockquote>"; 482 483 if ( $this->col_info ) 484 { 485 486 // ===================================================== 487 // Results top rows 488 489 $this->console .= "<table cellpadding=5 cellspacing=1 bgcolor=555555>"; 490 $this->console .= "<tr bgcolor=eeeeee><td nowrap valign=bottom><font color=555599 face=arial size=2><b>(row)</b></font></td>"; 491 492 493 for ( $i=0; $i < count($this->col_info); $i++ ) 494 { 495 $this->console .= "<td nowrap align=left valign=top><font size=1 color=555599 face=arial>{$this->col_info[$i]->type} {$this->col_info[$i]->max_length}</font><br><span style='font-family: arial; font-size: 10pt; font-weight: bold;'>{$this->col_info[$i]->name}</span></td>"; 496 } 497 498 $this->console .= "</tr>"; 499 500 // ====================================================== 501 // print main results 502 503 if ( $this->last_result ) 504 { 505 506 $i=0; 507 foreach ( $this->get_results(null,ARRAY_N) as $one_row ) 508 { 509 $i++; 510 $this->console .= "<tr bgcolor=ffffff><td bgcolor=eeeeee nowrap align=middle><font size=2 color=555599 face=arial>$i</font></td>"; 511 512 foreach ( $one_row as $item ) 513 { 514 $this->console .= "<td nowrap><font face=arial size=2>$item</font></td>"; 515 } 516 517 $this->console .= "</tr>"; 518 } 519 520 } // if last result 521 else 522 { 523 $this->console .= "<tr bgcolor=ffffff><td colspan=".(count($this->col_info)+1)."><font face=arial size=2>No Results</font></td></tr>"; 524 } 525 526 $this->console .= "</table>"; 527 528 } // if col_info 529 else 530 { 531 $this->console .= "<font face=arial size=2>No Results</font>"; 532 } 533 534 $this->console .= "</blockquote></blockquote>"; 535 $this->console .= $this->donation(); 536 $this->console .= "<hr noshade color=dddddd size=1>"; 537 538 // == TJH == more -- to try to make backward compatible with a default param that defaults to echo 539 if($this->debug_echo){ 540 echo $this->console; 541 } 542 543 $this->debug_called = true; 544 //echo "Something tested"; // == TJH == just some breadcrumbs for testing 545 } 546 547 548 549 /********************************************************************** 550 * Naughty little function to ask for some remuniration! 551 */ 552 553 function donation() 554 { 555 return "<font size=1 face=arial color=000000>If ezSQL has helped <a href="https://www.paypal.com/xclick/business=justin%40justinvincent.com&item_name=ezSQL&no_note=1&tax=0" style="color: 0000CC;">make a donation!?</a> <!--[ go on! you know you want to! ]--></font>"; 556 } 557 558 } 559 560 ?>
//ez_sql_core_2.1_debughack_0.2alpha.php
1 <?php 2 // ================================================================= 3 // == TJH == To provide optional return value as opposed to simple echo 4 // == TJH == of the $db->vardump and $db->debug functions 5 6 // == TJH == Helpful for assigning the output to a var for handling in situations like template 7 // == TJH == engines where you want the debugging output rendered in a particular location. 8 9 // == TJH == This latest version 0.2 alpha includes a modification that allows 10 // == TJH == the original dump and debug behaviours to be maintained by default 11 // == TJH == and hopefully be backward compatible with previous ezSQL versions 12 13 // == TJH == USAGE: $ezdump = print_r($db->vardump($result),true); 14 // == TJH == USAGE: $ezconsole = print_r($db->console,true); 15 16 // =========== n.b. for TBS template engine users ============================== 17 // === TJH === This is hacked to enable an ezSQL pop-up debug console from a TBS template page 18 // === TJH === The following steps need to be taken: 19 20 // === TJH === (1) Set $db->debug_all = true; // in your .php file 21 // === TJH === and $db->debug_echo = false; // in your .php file 22 23 // === TJH === (2) Add the following javascript to top of your html 24 /* 25 <ezdebugconsole> 26 [onload_1;block=ezdebugconsole;when [var.db.debug_all]=1] 27 <SCRIPT LANGUAGE="JavaScript"> 28 if(self.name == ''){var title = 'Console';} 29 else{var title = 'Console_' + self.name;} 30 newWindow = window.open("",title.value,"width=550,height=650,resizable,scrollbars=yes"); 31 newWindow.document.write("<HTML><HEAD><TITLE>ezSQL Debug [var..script_name;htmlconv=js]</TITLE></HEAD><BODY bgcolor=#e8e8e8>"); 32 // newWindow.document.write("<b>Debug for [var..script_name;htmlconv=js]</b><BR />"); 33 newWindow.document.write("<table border=0 width='100%'>"); 34 newWindow.document.write("[var.ezdebug;htmlconv=js]"); 35 newWindow.document.write("</body> </html> "); 36 </script> 37 </ezdebugconsole> 38 */ 39 40 // === TJH === (3) debug data is called with $db->console 41 // === TJH === Use something like 42 // === TJH === $ezdebug = print_r($db->console,true); 43 // === TJH === to stuff the debug data into a PHP var 44 // === TJH === 45 // === TJH === n.b. Don't forget to slurp the slug of javascript 46 // === TJH === at the top of the .html template page 47 // === TJH === you'll need to hack it if you're going to 48 // === TJH === use it other than with TBS tempalte engine. 49 // === TJH === 50 // === TJH === Search this file for "TJH" comments to find changes 51 // === TJH === You can contact TJH via http://tomhenry.us/ 52 // ================================================================= 53 54 /********************************************************************** 55 * Author: Justin Vincent (jv@jvmultimedia.com) 56 * Web...: http://twitter.com/justinvincent 57 * Name..: ezSQL 58 * Desc..: ezSQL Core module - database abstraction library to make 59 * it very easy to deal with databases. 60 * 61 */ 62 63 /********************************************************************** 64 * ezSQL Constants 65 */ 66 67 define('EZSQL_VERSION','2.1-console'); // === TJH === added an identifying flag to the version number 68 define('OBJECT','OBJECT',true); 69 define('ARRAY_A','ARRAY_A',true); 70 define('ARRAY_N','ARRAY_N',true); 71 define('EZSQL_CORE_ERROR','ezSQLcore can not be used by itself (it is designed for use by database specific modules).'); 72 73 74 /********************************************************************** 75 * Core class containg common functions to manipulate query result 76 * sets once returned 77 */ 78 79 class ezSQLcore 80 { 81 82 var $trace = false; // same as $debug_all 83 var $debug_all = false; // same as $trace 84 85 // === TJH === 86 var $debug_echo = true; // == TJH == // default now needed for echo of debug function 87 88 var $debug_called = false; 89 var $vardump_called = false; 90 var $show_errors = true; 91 var $num_queries = 0; 92 var $last_query = null; 93 var $last_error = null; 94 var $col_info = null; 95 var $captured_errors = array(); 96 97 /********************************************************************** 98 * Constructor 99 */ 100 101 function ezSQLcore() 102 { 103 } 104 105 /********************************************************************** 106 * Connect to DB - over-ridden by specific DB class 107 */ 108 109 function connect() 110 { 111 die(EZSQL_CORE_ERROR); 112 } 113 114 /********************************************************************** 115 * Select DB - over-ridden by specific DB class 116 */ 117 118 function select() 119 { 120 die(EZSQL_CORE_ERROR); 121 } 122 123 /********************************************************************** 124 * Basic Query - over-ridden by specific DB class 125 */ 126 127 function query() 128 { 129 die(EZSQL_CORE_ERROR); 130 } 131 132 /********************************************************************** 133 * Format a string correctly for safe insert - over-ridden by specific 134 * DB class 135 */ 136 137 function escape() 138 { 139 die(EZSQL_CORE_ERROR); 140 } 141 142 /********************************************************************** 143 * Return database specific system date syntax 144 * i.e. Oracle: SYSDATE Mysql: NOW() 145 */ 146 147 function sysdate() 148 { 149 die(EZSQL_CORE_ERROR); 150 } 151 152 /********************************************************************** 153 * Print SQL/DB error - over-ridden by specific DB class 154 */ 155 156 function register_error($err_str) 157 { 158 // Keep track of last error 159 $this->last_error = $err_str; 160 161 // Capture all errors to an error array no matter what happens 162 $this->captured_errors[] = array 163 ( 164 'error_str' => $err_str, 165 'query' => $this->last_query 166 ); 167 } 168 169 /********************************************************************** 170 * Turn error handling on or off.. 171 */ 172 173 function show_errors() 174 { 175 $this->show_errors = true; 176 } 177 178 function hide_errors() 179 { 180 $this->show_errors = false; 181 } 182 183 /********************************************************************** 184 * Kill cached query results 185 */ 186 187 function flush() 188 { 189 // Get rid of these 190 $this->last_result = null; 191 $this->col_info = null; 192 $this->last_query = null; 193 $this->from_disk_cache = false; 194 } 195 196 /********************************************************************** 197 * Get one variable from the DB - see docs for more detail 198 */ 199 200 function get_var($query=null,$x=0,$y=0) 201 { 202 203 // Log how the function was called 204 $this->func_call = "$db->get_var("$query",$x,$y)"; 205 206 // If there is a query then perform it if not then use cached results.. 207 if ( $query ) 208 { 209 $this->query($query); 210 } 211 212 // Extract var out of cached results based x,y vals 213 if ( $this->last_result[$y] ) 214 { 215 $values = array_values(get_object_vars($this->last_result[$y])); 216 } 217 218 // If there is a value return it else return null 219 return (isset($values[$x]) && $values[$x]!=='')?$values[$x]:null; 220 } 221 222 /********************************************************************** 223 * Get one row from the DB - see docs for more detail 224 */ 225 226 function get_row($query=null,$output=OBJECT,$y=0) 227 { 228 229 // Log how the function was called 230 $this->func_call = "$db->get_row("$query",$output,$y)"; 231 232 // If there is a query then perform it if not then use cached results.. 233 if ( $query ) 234 { 235 $this->query($query); 236 } 237 238 // If the output is an object then return object using the row offset.. 239 if ( $output == OBJECT ) 240 { 241 return $this->last_result[$y]?$this->last_result[$y]:null; 242 } 243 // If the output is an associative array then return row as such.. 244 elseif ( $output == ARRAY_A ) 245 { 246 return $this->last_result[$y]?get_object_vars($this->last_result[$y]):null; 247 } 248 // If the output is an numerical array then return row as such.. 249 elseif ( $output == ARRAY_N ) 250 { 251 return $this->last_result[$y]?array_values(get_object_vars($this->last_result[$y])):null; 252 } 253 // If invalid output type was specified.. 254 else 255 { 256 $this->print_error(" $db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N"); 257 } 258 259 } 260 261 /********************************************************************** 262 * Function to get 1 column from the cached result set based in X index 263 * see docs for usage and info 264 */ 265 266 function get_col($query=null,$x=0) 267 { 268 269 // If there is a query then perform it if not then use cached results.. 270 if ( $query ) 271 { 272 $this->query($query); 273 } 274 275 // Extract the column values 276 for ( $i=0; $i < count($this->last_result); $i++ ) 277 { 278 $new_array[$i] = $this->get_var(null,$x,$i); 279 } 280 281 return $new_array; 282 } 283 284 285 /********************************************************************** 286 * Return the the query as a result set - see docs for more details 287 */ 288 289 function get_results($query=null, $output = OBJECT) 290 { 291 292 // Log how the function was called 293 $this->func_call = "$db->get_results("$query", $output)"; 294 295 // If there is a query then perform it if not then use cached results.. 296 if ( $query ) 297 { 298 $this->query($query); 299 } 300 301 // Send back array of objects. Each row is an object 302 if ( $output == OBJECT ) 303 { 304 return $this->last_result; 305 } 306 elseif ( $output == ARRAY_A || $output == ARRAY_N ) 307 { 308 if ( $this->last_result ) 309 { 310 $i=0; 311 foreach( $this->last_result as $row ) 312 { 313 314 $new_array[$i] = get_object_vars($row); 315 316 if ( $output == ARRAY_N ) 317 { 318 $new_array[$i] = array_values($new_array[$i]); 319 } 320 321 $i++; 322 } 323 324 return $new_array; 325 } 326 else 327 { 328 return array(); 329 } 330 } 331 } 332 333 334 /********************************************************************** 335 * Function to get column meta data info pertaining to the last query 336 * see docs for more info and usage 337 */ 338 339 function get_col_info($info_type="name",$col_offset=-1) 340 { 341 342 if ( $this->col_info ) 343 { 344 if ( $col_offset == -1 ) 345 { 346 $i=0; 347 foreach($this->col_info as $col ) 348 { 349 $new_array[$i] = $col->{$info_type}; 350 $i++; 351 } 352 return $new_array; 353 } 354 else 355 { 356 return $this->col_info[$col_offset]->{$info_type}; 357 } 358 359 } 360 361 } 362 363 364 /********************************************************************** 365 * Dumps the contents of any input variable to screen in a nicely 366 * formatted and easy to understand way - any type: Object, Var or Array 367 */ 368 // === TJH === This is hacked to OPTIONALLY generate a "$return_var" 369 // === TJH === must also set $db->debug_echo = false; in your script to override default behaviour 370 // === TJH === instead of a simple "echo" to the current screen (DEFAULT) 371 // === TJH === USAGE: $ezdebug = print_r($db->vardump($result),true); 372 function vardump($mixed='') 373 { 374 $return_var .= "<p><table><tr><td bgcolor=ffffff><blockquote><font color=000090>"; 375 $return_var .= "<pre><font face=arial>"; 376 377 if ( ! $this->vardump_called ) 378 { 379 $return_var .= "<font color=800080><b>ezSQL</b> (v".EZSQL_VERSION.") <b>Variable Dump..</b></font> "; 380 } 381 382 $var_type = gettype ($mixed); 383 $return_var .= print_r(($mixed?$mixed:"<font color=red>No Value / False</font>"),true); 384 $return_var .= " <b>Type:</b> " . ucfirst($var_type) . " "; 385 $return_var .= "<b>Last Query</b> [$this->num_queries]<b>:</b> ".($this->last_query?$this->last_query:"NULL")." "; 386 $return_var .= "<b>Last Function Call:</b> " . ($this->func_call?$this->func_call:"None")." "; 387 $return_var .= "<b>Last Rows Returned:</b> ".count($this->last_result)." "; 388 $return_var .= "</font></pre></font></blockquote></td></tr></table>".$this->donation(); 389 $return_var .= " <hr size=1 noshade color=dddddd>"; 390 391 $this->vardump_called = true; 392 393 if($this->debug_echo){ 394 echo $return_var; 395 } 396 397 return $return_var; 398 } 399 400 /********************************************************************** 401 * Alias for the above function 402 */ 403 404 function dumpvar($mixed) 405 { 406 $this->vardump($mixed); 407 } 408 409 /********************************************************************** 410 * Displays the last query string that was sent to the database & a 411 * table listing results (if there were any). 412 * (abstracted into a seperate file to save server overhead). 413 */ 414 415 // === TJH === The debug() function is now hacked to OPTIOANLLY create a return result 416 // === TJH === that can be called as a variable, just changed all "echo"s to "$this->console .= " 417 // === TJH === this is accessed with "$db->console" obviously 418 // === TJH === n.b. you must also set $db->debug_echo = false; to override default behaviour 419 420 function debug($debug_echo) // === TJH === set a default for function to be able to switch "echo" on/off 421 { 422 423 //$this->console .= "<blockquote>"; // === TJH == commented out to change output formatting slightly 424 425 // Only show ezSQL credits once.. 426 if ( ! $this->debug_called ) 427 { 428 $this->console .= "<font color=800080 face=arial size=2><b>ezSQL</b> (v".EZSQL_VERSION.") <b>Debug..</b></font><p> "; 429 } 430 431 if ( $this->last_error ) 432 { 433 $this->console .= "<font face=arial size=2 color=000099><b>Last Error --</b> [<font color=000000><b>$this->last_error</b></font>]<p>"; 434 } 435 436 if ( $this->from_disk_cache ) 437 { 438 $this->console .= "<font face=arial size=2 color=000099><b>Results retrieved from disk cache</b></font><p>"; 439 } 440 441 $this->console .= "<font face=arial size=2 color=000099><b>Query</b> [$this->num_queries] <b>--</b> "; 442 $this->console .= "[<font color=000000><b>$this->last_query</b></font>]</font><p>"; 443 444 $this->console .= "<font face=arial size=2 color=000099><b>Query Result..</b></font>"; 445 $this->console .= "<blockquote>"; 446 447 if ( $this->col_info ) 448 { 449 450 // ===================================================== 451 // Results top rows 452 453 $this->console .= "<table cellpadding=5 cellspacing=1 bgcolor=555555>"; 454 $this->console .= "<tr bgcolor=eeeeee><td nowrap valign=bottom><font color=555599 face=arial size=2><b>(row)</b></font></td>"; 455 456 457 for ( $i=0; $i < count($this->col_info); $i++ ) 458 { 459 $this->console .= "<td nowrap align=left valign=top><font size=1 color=555599 face=arial>{$this->col_info[$i]->type} {$this->col_info[$i]->max_length}</font><br><span style='font-family: arial; font-size: 10pt; font-weight: bold;'>{$this->col_info[$i]->name}</span></td>"; 460 } 461 462 $this->console .= "</tr>"; 463 464 // ====================================================== 465 // print main results 466 467 if ( $this->last_result ) 468 { 469 470 $i=0; 471 foreach ( $this->get_results(null,ARRAY_N) as $one_row ) 472 { 473 $i++; 474 $this->console .= "<tr bgcolor=ffffff><td bgcolor=eeeeee nowrap align=middle><font size=2 color=555599 face=arial>$i</font></td>"; 475 476 foreach ( $one_row as $item ) 477 { 478 $this->console .= "<td nowrap><font face=arial size=2>$item</font></td>"; 479 } 480 481 $this->console .= "</tr>"; 482 } 483 484 } // if last result 485 else 486 { 487 $this->console .= "<tr bgcolor=ffffff><td colspan=".(count($this->col_info)+1)."><font face=arial size=2>No Results</font></td></tr>"; 488 } 489 490 $this->console .= "</table>"; 491 492 } // if col_info 493 else 494 { 495 $this->console .= "<font face=arial size=2>No Results</font>"; 496 } 497 498 $this->console .= "</blockquote></blockquote>"; 499 $this->console .= $this->donation(); 500 $this->console .= "<hr noshade color=dddddd size=1>"; 501 502 // == TJH == more -- to try to make backward compatible with a default param that defaults to echo 503 if($this->debug_echo){ 504 echo $this->console; 505 } 506 507 $this->debug_called = true; 508 //echo "Something tested"; // == TJH == just some breadcrumbs for testing 509 } 510 511 512 513 /********************************************************************** 514 * Naughty little function to ask for some remuniration! 515 */ 516 517 function donation() 518 { 519 return "<font size=1 face=arial color=000000>If ezSQL has helped <a href="https://www.paypal.com/xclick/business=justin%40justinvincent.com&item_name=ezSQL&no_note=1&tax=0" style="color: 0000CC;">make a donation!?</a> <!--[ go on! you know you want to! ]--></font>"; 520 } 521 522 } 523 524 ?>
readme_debughack_0.2alpha.txt
// =================================================================
// =================================================================
// == TJH == ezSQL Debug Console version 0.2-alpha ===============================
// =================================================================
// =================================================================
// == TJH == To provide optional return value as opposed to simple echo
// == TJH == of the $db->vardump and $db->debug functions
// == TJH == Helpful for assigning the output to a var for handling in situations like template
// == TJH == engines where you want the debugging output rendered in a particular location.
// == TJH == This latest version 0.2 alpha includes a modification that allows
// == TJH == the original dump and debug behaviours to be maintained by default
// == TJH == and hopefully be backward compatible with previous ezSQL versions
// == TJH == n.b. set $db->debug_all = true; // in your .php file
// == TJH == and $db->debug_echo = false; // in your .php file
// == TJH == USAGE: $ezdump = print_r($db->vardump($result),true);
// == TJH == USAGE: $ezdebug = print_r($db->console,true);
// =================================================================
// =================================================================
// =================================================================
// =========== n.b. for TBS template engine users ==============================
// === TJH === This is hacked to enable an ezSQL pop-up debug console from a TBS template page
// === TJH === The following steps need to be taken:
// === TJH === (1) Set $db->debug_all = true; // in your .php file
// === TJH === and $db->debug_echo = false; // in your .php file
// === TJH === (2) Add the following javascript to top of your html
/*
<ezdebugconsole>
[onload_1;block=ezdebugconsole;when [var.db.debug_all]=1]
<SCRIPT LANGUAGE="JavaScript">
if(self.name == ''){var title = 'Console';}
else{var title = 'Console_' + self.name;}
newWindow = window.open("",title.value,"width=550,height=650,resizable,scrollbars=yes");
newWindow.document.write("<HTML><HEAD><TITLE>ezSQL Debug [var..script_name;htmlconv=js]</TITLE></HEAD><BODY bgcolor=#e8e8e8>");
// newWindow.document.write("<b>Debug for [var..script_name;htmlconv=js]</b><BR />");
newWindow.document.write("<table border=0 width='100%'>");
newWindow.document.write("[var.ezdebug;htmlconv=js]");
newWindow.document.write("</body>
</html>
");
</script>
</ezdebugconsole>
*/
// === TJH === (3) debug data is called with $db->console
// === TJH === Use something like
// === TJH === $ezdebug = print_r($db->console,true);
// === TJH === to stuff the debug data into a PHP var
// === TJH ===
// === TJH === n.b. Don't forget to slurp the slug of javascript
// === TJH === at the top of the .html template page
// === TJH === you'll need to hack it if you're going to
// === TJH === use it other than with TBS tempalte engine.
// === TJH ===
// === TJH === Search this file for "TJH" comments to find changes
// === TJH === You can contact TJH via http://tomhenry.us/
// =================================================================