| [ Index ] |
PHP Cross Reference of Joomla 1.5.26 DE |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * @version $Id: mysqli.php 16385 2010-04-23 10:44:15Z ian $ 4 * @package Joomla.Framework 5 * @subpackage Database 6 * @copyright Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved. 7 * @license GNU/GPL, see LICENSE.php 8 * Joomla! is free software. This version may have been modified pursuant 9 * to the GNU General Public License, and as distributed it includes or 10 * is derivative of works licensed under the GNU General Public License or 11 * other free or open source software licenses. 12 * See COPYRIGHT.php for copyright notices and details. 13 */ 14 15 // Check to ensure this file is within the rest of the framework 16 defined('JPATH_BASE') or die(); 17 18 /** 19 * MySQLi database driver 20 * 21 * @package Joomla.Framework 22 * @subpackage Database 23 * @since 1.0 24 */ 25 class JDatabaseMySQLi extends JDatabase 26 { 27 /** 28 * The database driver name 29 * 30 * @var string 31 */ 32 var $name = 'mysqli'; 33 34 /** 35 * The null/zero date string 36 * 37 * @var string 38 */ 39 var $_nullDate = '0000-00-00 00:00:00'; 40 41 /** 42 * Quote for named objects 43 * 44 * @var string 45 */ 46 var $_nameQuote = '`'; 47 48 /** 49 * Database object constructor 50 * 51 * @access public 52 * @param array List of options used to configure the connection 53 * @since 1.5 54 * @see JDatabase 55 */ 56 function __construct( $options ) 57 { 58 $host = array_key_exists('host', $options) ? $options['host'] : 'localhost'; 59 $user = array_key_exists('user', $options) ? $options['user'] : ''; 60 $password = array_key_exists('password',$options) ? $options['password'] : ''; 61 $database = array_key_exists('database',$options) ? $options['database'] : ''; 62 $prefix = array_key_exists('prefix', $options) ? $options['prefix'] : 'jos_'; 63 $select = array_key_exists('select', $options) ? $options['select'] : true; 64 65 // Unlike mysql_connect(), mysqli_connect() takes the port and socket 66 // as separate arguments. Therefore, we have to extract them from the 67 // host string. 68 $port = NULL; 69 $socket = NULL; 70 $targetSlot = substr( strstr( $host, ":" ), 1 ); 71 if (!empty( $targetSlot )) { 72 // Get the port number or socket name 73 if (is_numeric( $targetSlot )) 74 $port = $targetSlot; 75 else 76 $socket = $targetSlot; 77 78 // Extract the host name only 79 $host = substr( $host, 0, strlen( $host ) - (strlen( $targetSlot ) + 1) ); 80 // This will take care of the following notation: ":3306" 81 if($host == '') 82 $host = 'localhost'; 83 } 84 85 // perform a number of fatality checks, then return gracefully 86 if (!function_exists( 'mysqli_connect' )) { 87 $this->_errorNum = 1; 88 $this->_errorMsg = 'The MySQL adapter "mysqli" is not available.'; 89 return; 90 } 91 92 // connect to the server 93 if (!($this->_resource = @mysqli_connect($host, $user, $password, NULL, $port, $socket))) { 94 $this->_errorNum = 2; 95 $this->_errorMsg = 'Could not connect to MySQL'; 96 return; 97 } 98 99 // finalize initialization 100 parent::__construct($options); 101 102 // select the database 103 if ( $select ) { 104 $this->select($database); 105 } 106 } 107 108 /** 109 * Database object destructor 110 * 111 * @return boolean 112 * @since 1.5 113 */ 114 function __destruct() 115 { 116 $return = false; 117 if (is_resource($this->_resource)) { 118 $return = mysqli_close($this->_resource); 119 } 120 return $return; 121 } 122 123 /** 124 * Test to see if the MySQLi connector is available 125 * 126 * @static 127 * @access public 128 * @return boolean True on success, false otherwise. 129 */ 130 function test() 131 { 132 return (function_exists( 'mysqli_connect' )); 133 } 134 135 /** 136 * Determines if the connection to the server is active. 137 * 138 * @access public 139 * @return boolean 140 * @since 1.5 141 */ 142 function connected() 143 { 144 return $this->_resource->ping(); 145 } 146 147 /** 148 * Select a database for use 149 * 150 * @access public 151 * @param string $database 152 * @return boolean True if the database has been successfully selected 153 * @since 1.5 154 */ 155 function select($database) 156 { 157 if ( ! $database ) 158 { 159 return false; 160 } 161 162 if ( !mysqli_select_db($this->_resource, $database)) { 163 $this->_errorNum = 3; 164 $this->_errorMsg = 'Could not connect to database'; 165 return false; 166 } 167 168 // if running mysql 5, set sql-mode to mysql40 - thereby circumventing strict mode problems 169 if ( strpos( $this->getVersion(), '5' ) === 0 ) { 170 $this->setQuery( "SET sql_mode = 'MYSQL40'" ); 171 $this->query(); 172 } 173 174 return true; 175 } 176 177 /** 178 * Determines UTF support 179 * 180 * @access public 181 * @return boolean True - UTF is supported 182 */ 183 function hasUTF() 184 { 185 $verParts = explode( '.', $this->getVersion() ); 186 return ($verParts[0] == 5 || ($verParts[0] == 4 && $verParts[1] == 1 && (int)$verParts[2] >= 2)); 187 } 188 189 /** 190 * Custom settings for UTF support 191 * 192 * @access public 193 */ 194 function setUTF() 195 { 196 mysqli_query( $this->_resource, "SET NAMES 'utf8'" ); 197 } 198 199 /** 200 * Get a database escaped string 201 * 202 * @param string The string to be escaped 203 * @param boolean Optional parameter to provide extra escaping 204 * @return string 205 * @access public 206 * @abstract 207 */ 208 function getEscaped( $text, $extra = false ) 209 { 210 $result = mysqli_real_escape_string( $this->_resource, $text ); 211 if ($extra) { 212 $result = addcslashes( $result, '%_' ); 213 } 214 return $result; 215 } 216 /** 217 * Execute the query 218 * 219 * @access public 220 * @return mixed A database resource if successful, FALSE if not. 221 */ 222 function query() 223 { 224 if (!is_object($this->_resource)) { 225 return false; 226 } 227 228 // Take a local copy so that we don't modify the original query and cause issues later 229 $sql = $this->_sql; 230 if ($this->_limit > 0 || $this->_offset > 0) { 231 $sql .= ' LIMIT ' . max($this->_offset, 0) . ', ' . max($this->_limit, 0); 232 } 233 if ($this->_debug) { 234 $this->_ticker++; 235 $this->_log[] = $sql; 236 } 237 $this->_errorNum = 0; 238 $this->_errorMsg = ''; 239 $this->_cursor = mysqli_query( $this->_resource, $sql ); 240 241 if (!$this->_cursor) 242 { 243 $this->_errorNum = mysqli_errno( $this->_resource ); 244 $this->_errorMsg = mysqli_error( $this->_resource )." SQL=$sql"; 245 246 if ($this->_debug) { 247 JError::raiseError(500, 'JDatabaseMySQL::query: '.$this->_errorNum.' - '.$this->_errorMsg ); 248 } 249 return false; 250 } 251 return $this->_cursor; 252 } 253 254 /** 255 * Description 256 * 257 * @access public 258 * @return int The number of affected rows in the previous operation 259 * @since 1.0.5 260 */ 261 function getAffectedRows() 262 { 263 return mysqli_affected_rows( $this->_resource ); 264 } 265 266 /** 267 * Execute a batch query 268 * 269 * @access public 270 * @return mixed A database resource if successful, FALSE if not. 271 */ 272 function queryBatch( $abort_on_error=true, $p_transaction_safe = false) 273 { 274 $this->_errorNum = 0; 275 $this->_errorMsg = ''; 276 if ($p_transaction_safe) { 277 $this->_sql = rtrim($this->_sql, "; \t\r\n\0"); 278 $si = $this->getVersion(); 279 preg_match_all( "/(\d+)\.(\d+)\.(\d+)/i", $si, $m ); 280 if ($m[1] >= 4) { 281 $this->_sql = 'START TRANSACTION;' . $this->_sql . '; COMMIT;'; 282 } else if ($m[2] >= 23 && $m[3] >= 19) { 283 $this->_sql = 'BEGIN WORK;' . $this->_sql . '; COMMIT;'; 284 } else if ($m[2] >= 23 && $m[3] >= 17) { 285 $this->_sql = 'BEGIN;' . $this->_sql . '; COMMIT;'; 286 } 287 } 288 $query_split = $this->splitSql($this->_sql); 289 $error = 0; 290 foreach ($query_split as $command_line) { 291 $command_line = trim( $command_line ); 292 if ($command_line != '') { 293 $this->_cursor = mysqli_query( $this->_resource, $command_line ); 294 if ($this->_debug) { 295 $this->_ticker++; 296 $this->_log[] = $command_line; 297 } 298 if (!$this->_cursor) { 299 $error = 1; 300 $this->_errorNum .= mysqli_errno( $this->_resource ) . ' '; 301 $this->_errorMsg .= mysqli_error( $this->_resource )." SQL=$command_line <br />"; 302 if ($abort_on_error) { 303 return $this->_cursor; 304 } 305 } 306 } 307 } 308 return $error ? false : true; 309 } 310 311 /** 312 * Diagnostic function 313 * 314 * @access public 315 * @return string 316 */ 317 function explain() 318 { 319 $temp = $this->_sql; 320 $this->_sql = "EXPLAIN $this->_sql"; 321 322 if (!($cur = $this->query())) { 323 return null; 324 } 325 $first = true; 326 327 $buffer = '<table id="explain-sql">'; 328 $buffer .= '<thead><tr><td colspan="99">'.$this->getQuery().'</td></tr>'; 329 while ($row = mysqli_fetch_assoc( $cur )) { 330 if ($first) { 331 $buffer .= '<tr>'; 332 foreach ($row as $k=>$v) { 333 $buffer .= '<th>'.$k.'</th>'; 334 } 335 $buffer .= '</tr>'; 336 $first = false; 337 } 338 $buffer .= '</thead><tbody><tr>'; 339 foreach ($row as $k=>$v) { 340 $buffer .= '<td>'.$v.'</td>'; 341 } 342 $buffer .= '</tr>'; 343 } 344 $buffer .= '</tbody></table>'; 345 mysqli_free_result( $cur ); 346 347 $this->_sql = $temp; 348 349 return $buffer; 350 } 351 352 /** 353 * Description 354 * 355 * @access public 356 * @return int The number of rows returned from the most recent query. 357 */ 358 function getNumRows( $cur=null ) 359 { 360 return mysqli_num_rows( $cur ? $cur : $this->_cursor ); 361 } 362 363 /** 364 * This method loads the first field of the first row returned by the query. 365 * 366 * @access public 367 * @return The value returned in the query or null if the query failed. 368 */ 369 function loadResult() 370 { 371 if (!($cur = $this->query())) { 372 return null; 373 } 374 $ret = null; 375 if ($row = mysqli_fetch_row( $cur )) { 376 $ret = $row[0]; 377 } 378 mysqli_free_result( $cur ); 379 return $ret; 380 } 381 382 /** 383 * Load an array of single field results into an array 384 * 385 * @access public 386 */ 387 function loadResultArray($numinarray = 0) 388 { 389 if (!($cur = $this->query())) { 390 return null; 391 } 392 $array = array(); 393 while ($row = mysqli_fetch_row( $cur )) { 394 $array[] = $row[$numinarray]; 395 } 396 mysqli_free_result( $cur ); 397 return $array; 398 } 399 400 /** 401 * Fetch a result row as an associative array 402 * 403 * @access public 404 * @return array 405 */ 406 function loadAssoc() 407 { 408 if (!($cur = $this->query())) { 409 return null; 410 } 411 $ret = null; 412 if ($array = mysqli_fetch_assoc( $cur )) { 413 $ret = $array; 414 } 415 mysqli_free_result( $cur ); 416 return $ret; 417 } 418 419 /** 420 * Load a assoc list of database rows 421 * 422 * @access public 423 * @param string The field name of a primary key 424 * @return array If <var>key</var> is empty as sequential list of returned records. 425 */ 426 function loadAssocList( $key='' ) 427 { 428 if (!($cur = $this->query())) { 429 return null; 430 } 431 $array = array(); 432 while ($row = mysqli_fetch_assoc( $cur )) { 433 if ($key) { 434 $array[$row[$key]] = $row; 435 } else { 436 $array[] = $row; 437 } 438 } 439 mysqli_free_result( $cur ); 440 return $array; 441 } 442 443 /** 444 * This global function loads the first row of a query into an object 445 * 446 * @access public 447 * @return object 448 */ 449 function loadObject( ) 450 { 451 if (!($cur = $this->query())) { 452 return null; 453 } 454 $ret = null; 455 if ($object = mysqli_fetch_object( $cur )) { 456 $ret = $object; 457 } 458 mysqli_free_result( $cur ); 459 return $ret; 460 } 461 462 /** 463 * Load a list of database objects 464 * 465 * If <var>key</var> is not empty then the returned array is indexed by the value 466 * the database key. Returns <var>null</var> if the query fails. 467 * 468 * @access public 469 * @param string The field name of a primary key 470 * @return array If <var>key</var> is empty as sequential list of returned records. 471 */ 472 function loadObjectList( $key='' ) 473 { 474 if (!($cur = $this->query())) { 475 return null; 476 } 477 $array = array(); 478 while ($row = mysqli_fetch_object( $cur )) { 479 if ($key) { 480 $array[$row->$key] = $row; 481 } else { 482 $array[] = $row; 483 } 484 } 485 mysqli_free_result( $cur ); 486 return $array; 487 } 488 489 /** 490 * Description 491 * 492 * @access public 493 * @return The first row of the query. 494 */ 495 function loadRow() 496 { 497 if (!($cur = $this->query())) { 498 return null; 499 } 500 $ret = null; 501 if ($row = mysqli_fetch_row( $cur )) { 502 $ret = $row; 503 } 504 mysqli_free_result( $cur ); 505 return $ret; 506 } 507 508 /** 509 * Load a list of database rows (numeric column indexing) 510 * 511 * If <var>key</var> is not empty then the returned array is indexed by the value 512 * the database key. Returns <var>null</var> if the query fails. 513 * 514 * @access public 515 * @param string The field name of a primary key 516 * @return array If <var>key</var> is empty as sequential list of returned records. 517 */ 518 function loadRowList( $key=null ) 519 { 520 if (!($cur = $this->query())) { 521 return null; 522 } 523 $array = array(); 524 while ($row = mysqli_fetch_row( $cur )) { 525 if ($key !== null) { 526 $array[$row[$key]] = $row; 527 } else { 528 $array[] = $row; 529 } 530 } 531 mysqli_free_result( $cur ); 532 return $array; 533 } 534 535 /** 536 * Inserts a row into a table based on an objects properties 537 * 538 * @access public 539 * @param string The name of the table 540 * @param object An object whose properties match table fields 541 * @param string The name of the primary key. If provided the object property is updated. 542 */ 543 function insertObject( $table, &$object, $keyName = NULL ) 544 { 545 $fmtsql = 'INSERT INTO '.$this->nameQuote($table).' ( %s ) VALUES ( %s ) '; 546 $fields = array(); 547 foreach (get_object_vars( $object ) as $k => $v) { 548 if (is_array($v) or is_object($v) or $v === NULL) { 549 continue; 550 } 551 if ($k[0] == '_') { // internal field 552 continue; 553 } 554 $fields[] = $this->nameQuote( $k ); 555 $values[] = $this->isQuoted( $k ) ? $this->Quote( $v ) : (int) $v; 556 } 557 $this->setQuery( sprintf( $fmtsql, implode( ",", $fields ) , implode( ",", $values ) ) ); 558 if (!$this->query()) { 559 return false; 560 } 561 $id = $this->insertid(); 562 if ($keyName && $id) { 563 $object->$keyName = $id; 564 } 565 return true; 566 } 567 568 /** 569 * Description 570 * 571 * @access public 572 * @param [type] $updateNulls 573 */ 574 function updateObject( $table, &$object, $keyName, $updateNulls=true ) 575 { 576 $fmtsql = 'UPDATE '.$this->nameQuote($table).' SET %s WHERE %s'; 577 $tmp = array(); 578 foreach (get_object_vars( $object ) as $k => $v) { 579 if( is_array($v) or is_object($v) or $k[0] == '_' ) { // internal or NA field 580 continue; 581 } 582 if( $k == $keyName ) { // PK not to be updated 583 $where = $keyName . '=' . $this->Quote( $v ); 584 continue; 585 } 586 if ($v === null) 587 { 588 if ($updateNulls) { 589 $val = 'NULL'; 590 } else { 591 continue; 592 } 593 } else { 594 $val = $this->isQuoted( $k ) ? $this->Quote( $v ) : (int) $v; 595 } 596 $tmp[] = $this->nameQuote( $k ) . '=' . $val; 597 } 598 $this->setQuery( sprintf( $fmtsql, implode( ",", $tmp ) , $where ) ); 599 return $this->query(); 600 } 601 602 /** 603 * Description 604 * 605 * @access public 606 */ 607 function insertid() 608 { 609 return mysqli_insert_id( $this->_resource ); 610 } 611 612 /** 613 * Description 614 * 615 * @access public 616 */ 617 function getVersion() 618 { 619 return mysqli_get_server_info( $this->_resource ); 620 } 621 622 /** 623 * Assumes database collation in use by sampling one text field in one table 624 * 625 * @access public 626 * @return string Collation in use 627 */ 628 function getCollation () 629 { 630 if ( $this->hasUTF() ) { 631 $this->setQuery( 'SHOW FULL COLUMNS FROM #__content' ); 632 $array = $this->loadAssocList(); 633 return $array['4']['Collation']; 634 } else { 635 return "N/A (mySQL < 4.1.2)"; 636 } 637 } 638 639 /** 640 * Description 641 * 642 * @access public 643 * @return array A list of all the tables in the database 644 */ 645 function getTableList() 646 { 647 $this->setQuery( 'SHOW TABLES' ); 648 return $this->loadResultArray(); 649 } 650 651 /** 652 * Shows the CREATE TABLE statement that creates the given tables 653 * 654 * @access public 655 * @param array|string A table name or a list of table names 656 * @return array A list the create SQL for the tables 657 */ 658 function getTableCreate( $tables ) 659 { 660 settype($tables, 'array'); //force to array 661 $result = array(); 662 663 foreach ($tables as $tblval) 664 { 665 $this->setQuery( 'SHOW CREATE table ' . $this->getEscaped( $tblval ) ); 666 $rows = $this->loadRowList(); 667 foreach ($rows as $row) { 668 $result[$tblval] = $row[1]; 669 } 670 } 671 672 return $result; 673 } 674 675 /** 676 * Retrieves information about the given tables 677 * 678 * @access public 679 * @param array|string A table name or a list of table names 680 * @param boolean Only return field types, default true 681 * @return array An array of fields by table 682 */ 683 function getTableFields( $tables, $typeonly = true ) 684 { 685 settype($tables, 'array'); //force to array 686 $result = array(); 687 688 foreach ($tables as $tblval) 689 { 690 $this->setQuery( 'SHOW FIELDS FROM ' . $tblval ); 691 $fields = $this->loadObjectList(); 692 693 if($typeonly) 694 { 695 foreach ($fields as $field) { 696 $result[$tblval][$field->Field] = preg_replace("/[(0-9)]/",'', $field->Type ); 697 } 698 } 699 else 700 { 701 foreach ($fields as $field) { 702 $result[$tblval][$field->Field] = $field; 703 } 704 } 705 } 706 707 return $result; 708 } 709 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Mar 28 15:54:07 2012 | Cross-referenced by PHPXref 0.7.1 |