[ Index ]

PHP Cross Reference of Joomla 1.5.26 DE

title

Body

[close]

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

   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  }


Generated: Wed Mar 28 15:54:07 2012 Cross-referenced by PHPXref 0.7.1