[ Index ]

PHP Cross Reference of Joomla 2.5.4 DE

title

Body

[close]

/libraries/joomla/database/database/ -> mysqli.php (source)

   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  }


Generated: Tue Apr 3 11:40:28 2012 Cross-referenced by PHPXref 0.7.1