| [ Index ] |
PHP Cross Reference of Joomla 2.5.4 DE |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * @package Joomla.Platform 4 * @subpackage Database 5 * 6 * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved. 7 * @license GNU General Public License version 2 or later; see LICENSE 8 */ 9 10 defined('JPATH_PLATFORM') or die; 11 12 JLoader::register('JDatabaseMySQL', dirname(__FILE__) . '/mysql.php'); 13 JLoader::register('JDatabaseQueryMySQLi', dirname(__FILE__) . '/mysqliquery.php'); 14 JLoader::register('JDatabaseExporterMySQLi', dirname(__FILE__) . '/mysqliexporter.php'); 15 JLoader::register('JDatabaseImporterMySQLi', dirname(__FILE__) . '/mysqliimporter.php'); 16 17 /** 18 * MySQLi database driver 19 * 20 * @package Joomla.Platform 21 * @subpackage Database 22 * @see http://php.net/manual/en/book.mysqli.php 23 * @since 11.1 24 */ 25 class JDatabaseMySQLi extends JDatabaseMySQL 26 { 27 /** 28 * The name of the database driver. 29 * 30 * @var string 31 * @since 11.1 32 */ 33 public $name = 'mysqli'; 34 35 /** 36 * Constructor. 37 * 38 * @param array $options List of options used to configure the connection 39 * 40 * @since 11.1 41 */ 42 protected function __construct($options) 43 { 44 // Get some basic values from the options. 45 $options['host'] = (isset($options['host'])) ? $options['host'] : 'localhost'; 46 $options['user'] = (isset($options['user'])) ? $options['user'] : 'root'; 47 $options['password'] = (isset($options['password'])) ? $options['password'] : ''; 48 $options['database'] = (isset($options['database'])) ? $options['database'] : ''; 49 $options['select'] = (isset($options['select'])) ? (bool) $options['select'] : true; 50 $options['port'] = null; 51 $options['socket'] = null; 52 53 /* 54 * Unlike mysql_connect(), mysqli_connect() takes the port and socket as separate arguments. Therefore, we 55 * have to extract them from the host string. 56 */ 57 $tmp = substr(strstr($options['host'], ':'), 1); 58 if (!empty($tmp)) 59 { 60 // Get the port number or socket name 61 if (is_numeric($tmp)) 62 { 63 $options['port'] = $tmp; 64 } 65 else 66 { 67 $options['socket'] = $tmp; 68 } 69 70 // Extract the host name only 71 $options['host'] = substr($options['host'], 0, strlen($options['host']) - (strlen($tmp) + 1)); 72 73 // This will take care of the following notation: ":3306" 74 if ($options['host'] == '') 75 { 76 $options['host'] = 'localhost'; 77 } 78 } 79 80 // Make sure the MySQLi extension for PHP is installed and enabled. 81 if (!function_exists('mysqli_connect')) 82 { 83 84 // Legacy error handling switch based on the JError::$legacy switch. 85 // @deprecated 12.1 86 if (JError::$legacy) 87 { 88 $this->errorNum = 1; 89 $this->errorMsg = JText::_('JLIB_DATABASE_ERROR_ADAPTER_MYSQLI'); 90 return; 91 } 92 else 93 { 94 throw new JDatabaseException(JText::_('JLIB_DATABASE_ERROR_ADAPTER_MYSQLI')); 95 } 96 } 97 98 $this->connection = @mysqli_connect( 99 $options['host'], $options['user'], $options['password'], null, $options['port'], $options['socket'] 100 ); 101 102 // Attempt to connect to the server. 103 if (!$this->connection) 104 { 105 // Legacy error handling switch based on the JError::$legacy switch. 106 // @deprecated 12.1 107 if (JError::$legacy) 108 { 109 $this->errorNum = 2; 110 $this->errorMsg = JText::_('JLIB_DATABASE_ERROR_CONNECT_MYSQL'); 111 return; 112 } 113 else 114 { 115 throw new JDatabaseException(JText::_('JLIB_DATABASE_ERROR_CONNECT_MYSQL')); 116 } 117 } 118 119 // Finalize initialisation 120 JDatabase::__construct($options); 121 122 // Set sql_mode to non_strict mode 123 mysqli_query($this->connection, "SET @@SESSION.sql_mode = '';"); 124 125 // If auto-select is enabled select the given database. 126 if ($options['select'] && !empty($options['database'])) 127 { 128 $this->select($options['database']); 129 } 130 } 131 132 /** 133 * Destructor. 134 * 135 * @since 11.1 136 */ 137 public function __destruct() 138 { 139 if (is_callable($this->connection, 'close')) 140 { 141 mysqli_close($this->connection); 142 } 143 } 144 145 /** 146 * Method to escape a string for usage in an SQL statement. 147 * 148 * @param string $text The string to be escaped. 149 * @param boolean $extra Optional parameter to provide extra escaping. 150 * 151 * @return string The escaped string. 152 * 153 * @since 11.1 154 */ 155 public function escape($text, $extra = false) 156 { 157 $result = mysqli_real_escape_string($this->getConnection(), $text); 158 159 if ($extra) 160 { 161 $result = addcslashes($result, '%_'); 162 } 163 164 return $result; 165 } 166 167 /** 168 * Test to see if the MySQL connector is available. 169 * 170 * @return boolean True on success, false otherwise. 171 * 172 * @since 11.1 173 */ 174 public static function test() 175 { 176 return (function_exists('mysqli_connect')); 177 } 178 179 /** 180 * Determines if the connection to the server is active. 181 * 182 * @return boolean True if connected to the database engine. 183 * 184 * @since 11.1 185 */ 186 public function connected() 187 { 188 if (is_object($this->connection)) 189 { 190 return mysqli_ping($this->connection); 191 } 192 193 return false; 194 } 195 196 /** 197 * Get the number of affected rows for the previous executed SQL statement. 198 * 199 * @return integer The number of affected rows. 200 * 201 * @since 11.1 202 */ 203 public function getAffectedRows() 204 { 205 return mysqli_affected_rows($this->connection); 206 } 207 208 /** 209 * Gets an exporter class object. 210 * 211 * @return JDatabaseExporterMySQLi An exporter object. 212 * 213 * @since 11.1 214 * @throws JDatabaseException 215 */ 216 public function getExporter() 217 { 218 // Make sure we have an exporter class for this driver. 219 if (!class_exists('JDatabaseExporterMySQLi')) 220 { 221 throw new JDatabaseException(JText::_('JLIB_DATABASE_ERROR_MISSING_EXPORTER')); 222 } 223 224 $o = new JDatabaseExporterMySQLi; 225 $o->setDbo($this); 226 227 return $o; 228 } 229 230 /** 231 * Gets an importer class object. 232 * 233 * @return JDatabaseImporterMySQLi An importer object. 234 * 235 * @since 11.1 236 * @throws JDatabaseException 237 */ 238 public function getImporter() 239 { 240 // Make sure we have an importer class for this driver. 241 if (!class_exists('JDatabaseImporterMySQLi')) 242 { 243 throw new JDatabaseException(JText::_('JLIB_DATABASE_ERROR_MISSING_IMPORTER')); 244 } 245 246 $o = new JDatabaseImporterMySQLi; 247 $o->setDbo($this); 248 249 return $o; 250 } 251 252 /** 253 * Get the number of returned rows for the previous executed SQL statement. 254 * 255 * @param resource $cursor An optional database cursor resource to extract the row count from. 256 * 257 * @return integer The number of returned rows. 258 * 259 * @since 11.1 260 */ 261 public function getNumRows($cursor = null) 262 { 263 return mysqli_num_rows($cursor ? $cursor : $this->cursor); 264 } 265 266 /** 267 * Get the current or query, or new JDatabaseQuery object. 268 * 269 * @param boolean $new False to return the last query set, True to return a new JDatabaseQuery object. 270 * 271 * @return mixed The current value of the internal SQL variable or a new JDatabaseQuery object. 272 * 273 * @since 11.1 274 * @throws JDatabaseException 275 */ 276 public function getQuery($new = false) 277 { 278 if ($new) 279 { 280 // Make sure we have a query class for this driver. 281 if (!class_exists('JDatabaseQueryMySQLi')) 282 { 283 throw new JDatabaseException(JText::_('JLIB_DATABASE_ERROR_MISSING_QUERY')); 284 } 285 return new JDatabaseQueryMySQLi($this); 286 } 287 else 288 { 289 return $this->sql; 290 } 291 } 292 293 /** 294 * Get the version of the database connector. 295 * 296 * @return string The database connector version. 297 * 298 * @since 11.1 299 */ 300 public function getVersion() 301 { 302 return mysqli_get_server_info($this->connection); 303 } 304 305 /** 306 * Determines if the database engine supports UTF-8 character encoding. 307 * 308 * @return boolean True if supported. 309 * 310 * @since 11.1 311 * @deprecated 12.1 312 */ 313 public function hasUTF() 314 { 315 JLog::add('JDatabaseMySQLi::hasUTF() is deprecated.', JLog::WARNING, 'deprecated'); 316 return true; 317 } 318 319 /** 320 * Method to get the auto-incremented value from the last INSERT statement. 321 * 322 * @return integer The value of the auto-increment field from the last inserted row. 323 * 324 * @since 11.1 325 */ 326 public function insertid() 327 { 328 return mysqli_insert_id($this->connection); 329 } 330 331 /** 332 * Execute the SQL statement. 333 * 334 * @return mixed A database cursor resource on success, boolean false on failure. 335 * 336 * @since 11.1 337 * @throws JDatabaseException 338 */ 339 public function query() 340 { 341 if (!is_object($this->connection)) 342 { 343 // Legacy error handling switch based on the JError::$legacy switch. 344 // @deprecated 12.1 345 if (JError::$legacy) 346 { 347 if ($this->debug) 348 { 349 JError::raiseError(500, 'JDatabaseMySQLi::query: ' . $this->errorNum . ' - ' . $this->errorMsg); 350 } 351 return false; 352 } 353 else 354 { 355 JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database'); 356 throw new JDatabaseException($this->errorMsg, $this->errorNum); 357 } 358 } 359 360 // Take a local copy so that we don't modify the original query and cause issues later 361 $sql = $this->replacePrefix((string) $this->sql); 362 if ($this->limit > 0 || $this->offset > 0) 363 { 364 $sql .= ' LIMIT ' . $this->offset . ', ' . $this->limit; 365 } 366 367 // If debugging is enabled then let's log the query. 368 if ($this->debug) 369 { 370 // Increment the query counter and add the query to the object queue. 371 $this->count++; 372 $this->log[] = $sql; 373 374 JLog::add($sql, JLog::DEBUG, 'databasequery'); 375 } 376 377 // Reset the error values. 378 $this->errorNum = 0; 379 $this->errorMsg = ''; 380 381 // Execute the query. 382 $this->cursor = mysqli_query($this->connection, $sql); 383 384 // If an error occurred handle it. 385 if (!$this->cursor) 386 { 387 $this->errorNum = (int) mysqli_errno($this->connection); 388 $this->errorMsg = (string) mysqli_error($this->connection) . ' SQL=' . $sql; 389 390 // Legacy error handling switch based on the JError::$legacy switch. 391 // @deprecated 12.1 392 if (JError::$legacy) 393 { 394 if ($this->debug) 395 { 396 JError::raiseError(500, 'JDatabaseMySQLi::query: ' . $this->errorNum . ' - ' . $this->errorMsg); 397 } 398 return false; 399 } 400 else 401 { 402 JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'databasequery'); 403 throw new JDatabaseException($this->errorMsg, $this->errorNum); 404 } 405 } 406 407 return $this->cursor; 408 } 409 410 /** 411 * Select a database for use. 412 * 413 * @param string $database The name of the database to select for use. 414 * 415 * @return boolean True if the database was successfully selected. 416 * 417 * @since 11.1 418 * @throws JDatabaseException 419 */ 420 public function select($database) 421 { 422 if (!$database) 423 { 424 return false; 425 } 426 427 if (!mysqli_select_db($this->connection, $database)) 428 { 429 // Legacy error handling switch based on the JError::$legacy switch. 430 // @deprecated 12.1 431 if (JError::$legacy) 432 { 433 $this->errorNum = 3; 434 $this->errorMsg = JText::_('JLIB_DATABASE_ERROR_DATABASE_CONNECT'); 435 return false; 436 } 437 else 438 { 439 throw new JDatabaseException(JText::_('JLIB_DATABASE_ERROR_DATABASE_CONNECT')); 440 } 441 } 442 443 return true; 444 } 445 446 /** 447 * Set the connection to use UTF-8 character encoding. 448 * 449 * @return boolean True on success. 450 * 451 * @since 11.1 452 */ 453 public function setUTF() 454 { 455 mysqli_query($this->connection, "SET NAMES 'utf8'"); 456 } 457 458 /** 459 * Method to fetch a row from the result set cursor as an array. 460 * 461 * @param mixed $cursor The optional result set cursor from which to fetch the row. 462 * 463 * @return mixed Either the next row from the result set or false if there are no more rows. 464 * 465 * @since 11.1 466 */ 467 protected function fetchArray($cursor = null) 468 { 469 return mysqli_fetch_row($cursor ? $cursor : $this->cursor); 470 } 471 472 /** 473 * Method to fetch a row from the result set cursor as an associative array. 474 * 475 * @param mixed $cursor The optional result set cursor from which to fetch the row. 476 * 477 * @return mixed Either the next row from the result set or false if there are no more rows. 478 * 479 * @since 11.1 480 */ 481 protected function fetchAssoc($cursor = null) 482 { 483 return mysqli_fetch_assoc($cursor ? $cursor : $this->cursor); 484 } 485 486 /** 487 * Method to fetch a row from the result set cursor as an object. 488 * 489 * @param mixed $cursor The optional result set cursor from which to fetch the row. 490 * @param string $class The class name to use for the returned row object. 491 * 492 * @return mixed Either the next row from the result set or false if there are no more rows. 493 * 494 * @since 11.1 495 */ 496 protected function fetchObject($cursor = null, $class = 'stdClass') 497 { 498 return mysqli_fetch_object($cursor ? $cursor : $this->cursor, $class); 499 } 500 501 /** 502 * Method to free up the memory used for the result set. 503 * 504 * @param mixed $cursor The optional result set cursor from which to fetch the row. 505 * 506 * @return void 507 * 508 * @since 11.1 509 */ 510 protected function freeResult($cursor = null) 511 { 512 mysqli_free_result($cursor ? $cursor : $this->cursor); 513 } 514 515 /** 516 * Execute a query batch. 517 * 518 * @param boolean $abortOnError Abort on error. 519 * @param boolean $transactionSafe Transaction safe queries. 520 * 521 * @return mixed A database resource if successful, false if not. 522 * 523 * @deprecated 12.1 524 * @since 11.1 525 */ 526 public function queryBatch($abortOnError = true, $transactionSafe = false) 527 { 528 // Deprecation warning. 529 JLog::add('JDatabaseMySQLi::queryBatch() is deprecated.', JLog::WARNING, 'deprecated'); 530 531 $sql = $this->replacePrefix((string) $this->sql); 532 $this->errorNum = 0; 533 $this->errorMsg = ''; 534 535 // If the batch is meant to be transaction safe then we need to wrap it in a transaction. 536 if ($transactionSafe) 537 { 538 $sql = 'START TRANSACTION;' . rtrim($sql, "; \t\r\n\0") . '; COMMIT;'; 539 } 540 $queries = $this->splitSql($sql); 541 $error = 0; 542 foreach ($queries as $query) 543 { 544 $query = trim($query); 545 if ($query != '') 546 { 547 $this->cursor = mysqli_query($this->connection, $query); 548 if ($this->debug) 549 { 550 $this->count++; 551 $this->log[] = $query; 552 } 553 if (!$this->cursor) 554 { 555 $error = 1; 556 $this->errorNum .= mysqli_errno($this->connection) . ' '; 557 $this->errorMsg .= mysqli_error($this->connection) . " SQL=$query <br />"; 558 if ($abortOnError) 559 { 560 return $this->cursor; 561 } 562 } 563 } 564 } 565 return $error ? false : true; 566 } 567 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Tue Apr 3 11:40:28 2012 | Cross-referenced by PHPXref 0.7.1 |