[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/phpbb/db/driver/ -> mysqli.php (source)

   1  <?php
   2  /**
   3  *
   4  * This file is part of the phpBB Forum Software package.
   5  *
   6  * @copyright (c) phpBB Limited <https://www.phpbb.com>
   7  * @license GNU General Public License, version 2 (GPL-2.0)
   8  *
   9  * For full copyright and license information, please see
  10  * the docs/CREDITS.txt file.
  11  *
  12  */
  13  
  14  namespace phpbb\db\driver;
  15  
  16  /**
  17  * MySQLi Database Abstraction Layer
  18  * mysqli-extension has to be compiled with:
  19  * MySQL 4.1+ or MySQL 5.0+
  20  */
  21  class mysqli extends \phpbb\db\driver\mysql_base
  22  {
  23      var $multi_insert = true;
  24      var $connect_error = '';
  25  
  26      /**
  27      * {@inheritDoc}
  28      */
  29  	function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
  30      {
  31          if (!function_exists('mysqli_connect'))
  32          {
  33              $this->connect_error = 'mysqli_connect function does not exist, is mysqli extension installed?';
  34              return $this->sql_error('');
  35          }
  36  
  37          $this->persistency = $persistency;
  38          $this->user = $sqluser;
  39  
  40          // If persistent connection, set dbhost to localhost when empty and prepend it with 'p:' prefix
  41          $this->server = ($this->persistency) ? 'p:' . (($sqlserver) ? $sqlserver : 'localhost') : $sqlserver;
  42  
  43          $this->dbname = $database;
  44          $port = (!$port) ? null : $port;
  45  
  46          // If port is set and it is not numeric, most likely mysqli socket is set.
  47          // Try to map it to the $socket parameter.
  48          $socket = null;
  49          if ($port)
  50          {
  51              if (is_numeric($port))
  52              {
  53                  $port = (int) $port;
  54              }
  55              else
  56              {
  57                  $socket = $port;
  58                  $port = null;
  59              }
  60          }
  61  
  62          $this->db_connect_id = mysqli_init();
  63  
  64          if (!@mysqli_real_connect($this->db_connect_id, $this->server, $this->user, $sqlpassword, $this->dbname, $port, $socket, MYSQLI_CLIENT_FOUND_ROWS))
  65          {
  66              $this->db_connect_id = '';
  67          }
  68  
  69          if ($this->db_connect_id && $this->dbname != '')
  70          {
  71              // Disable loading local files on client side
  72              @mysqli_options($this->db_connect_id, MYSQLI_OPT_LOCAL_INFILE, false);
  73  
  74              /*
  75               * As of PHP 8.1 MySQLi default error mode is set to MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT
  76               * See https://wiki.php.net/rfc/mysqli_default_errmode
  77               * Since phpBB implements own SQL errors handling, explicitly set it back to MYSQLI_REPORT_OFF
  78               */
  79              mysqli_report(MYSQLI_REPORT_OFF);
  80  
  81              @mysqli_query($this->db_connect_id, "SET NAMES 'utf8'");
  82  
  83              // enforce strict mode on databases that support it
  84              if (version_compare($this->sql_server_info(true), '5.0.2', '>='))
  85              {
  86                  $result = @mysqli_query($this->db_connect_id, 'SELECT @@session.sql_mode AS sql_mode');
  87                  if ($result)
  88                  {
  89                      $row = mysqli_fetch_assoc($result);
  90                      mysqli_free_result($result);
  91  
  92                      $modes = array_map('trim', explode(',', $row['sql_mode']));
  93                  }
  94                  else
  95                  {
  96                      $modes = array();
  97                  }
  98  
  99                  // TRADITIONAL includes STRICT_ALL_TABLES and STRICT_TRANS_TABLES
 100                  if (!in_array('TRADITIONAL', $modes))
 101                  {
 102                      if (!in_array('STRICT_ALL_TABLES', $modes))
 103                      {
 104                          $modes[] = 'STRICT_ALL_TABLES';
 105                      }
 106  
 107                      if (!in_array('STRICT_TRANS_TABLES', $modes))
 108                      {
 109                          $modes[] = 'STRICT_TRANS_TABLES';
 110                      }
 111                  }
 112  
 113                  $mode = implode(',', $modes);
 114                  @mysqli_query($this->db_connect_id, "SET SESSION sql_mode='{$mode}'");
 115              }
 116              return $this->db_connect_id;
 117          }
 118  
 119          return $this->sql_error('');
 120      }
 121  
 122      /**
 123      * {@inheritDoc}
 124      */
 125  	function sql_server_info($raw = false, $use_cache = true)
 126      {
 127          global $cache;
 128  
 129          if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('mysqli_version')) === false)
 130          {
 131              $result = @mysqli_query($this->db_connect_id, 'SELECT VERSION() AS version');
 132              if ($result)
 133              {
 134                  $row = mysqli_fetch_assoc($result);
 135                  mysqli_free_result($result);
 136  
 137                  $this->sql_server_version = $row['version'];
 138  
 139                  if (!empty($cache) && $use_cache)
 140                  {
 141                      $cache->put('mysqli_version', $this->sql_server_version);
 142                  }
 143              }
 144          }
 145  
 146          return ($raw) ? $this->sql_server_version : 'MySQL(i) ' . $this->sql_server_version;
 147      }
 148  
 149      /**
 150      * SQL Transaction
 151      * @access private
 152      */
 153  	function _sql_transaction($status = 'begin')
 154      {
 155          switch ($status)
 156          {
 157              case 'begin':
 158                  @mysqli_autocommit($this->db_connect_id, false);
 159                  $result = @mysqli_begin_transaction($this->db_connect_id);
 160                  return $result;
 161              break;
 162  
 163              case 'commit':
 164                  $result = @mysqli_commit($this->db_connect_id);
 165                  @mysqli_autocommit($this->db_connect_id, true);
 166                  return $result;
 167              break;
 168  
 169              case 'rollback':
 170                  $result = @mysqli_rollback($this->db_connect_id);
 171                  @mysqli_autocommit($this->db_connect_id, true);
 172                  return $result;
 173              break;
 174          }
 175  
 176          return true;
 177      }
 178  
 179      /**
 180      * {@inheritDoc}
 181      */
 182  	function sql_query($query = '', $cache_ttl = 0)
 183      {
 184          if ($query != '')
 185          {
 186              global $cache;
 187  
 188              if ($this->debug_sql_explain)
 189              {
 190                  $this->sql_report('start', $query);
 191              }
 192              else if ($this->debug_load_time)
 193              {
 194                  $this->curtime = microtime(true);
 195              }
 196  
 197              $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false;
 198              $this->sql_add_num_queries($this->query_result);
 199  
 200              if ($this->query_result === false)
 201              {
 202                  try
 203                  {
 204                      $this->query_result = @mysqli_query($this->db_connect_id, $query);
 205                  }
 206                  catch (\Error $e)
 207                  {
 208                      // Do nothing as SQL driver will report the error
 209                  }
 210  
 211                  if ($this->query_result === false)
 212                  {
 213                      $this->sql_error($query);
 214                  }
 215  
 216                  if ($this->debug_sql_explain)
 217                  {
 218                      $this->sql_report('stop', $query);
 219                  }
 220                  else if ($this->debug_load_time)
 221                  {
 222                      $this->sql_time += microtime(true) - $this->curtime;
 223                  }
 224  
 225                  if (!$this->query_result)
 226                  {
 227                      return false;
 228                  }
 229  
 230                  if ($cache && $cache_ttl)
 231                  {
 232                      $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl);
 233                  }
 234              }
 235              else if ($this->debug_sql_explain)
 236              {
 237                  $this->sql_report('fromcache', $query);
 238              }
 239          }
 240          else
 241          {
 242              return false;
 243          }
 244  
 245          return $this->query_result;
 246      }
 247  
 248      /**
 249      * {@inheritDoc}
 250      */
 251  	function sql_affectedrows()
 252      {
 253          return ($this->db_connect_id) ? @mysqli_affected_rows($this->db_connect_id) : false;
 254      }
 255  
 256      /**
 257      * {@inheritDoc}
 258      */
 259  	function sql_fetchrow($query_id = false)
 260      {
 261          global $cache;
 262  
 263          if ($query_id === false)
 264          {
 265              $query_id = $this->query_result;
 266          }
 267  
 268          $safe_query_id = $this->clean_query_id($query_id);
 269          if ($cache && $cache->sql_exists($safe_query_id))
 270          {
 271              return $cache->sql_fetchrow($safe_query_id);
 272          }
 273  
 274          if ($query_id)
 275          {
 276              $result = mysqli_fetch_assoc($query_id);
 277              return $result !== null ? $result : false;
 278          }
 279  
 280          return false;
 281      }
 282  
 283      /**
 284      * {@inheritDoc}
 285      */
 286  	function sql_rowseek($rownum, &$query_id)
 287      {
 288          global $cache;
 289  
 290          if ($query_id === false)
 291          {
 292              $query_id = $this->query_result;
 293          }
 294  
 295          $safe_query_id = $this->clean_query_id($query_id);
 296          if ($cache && $cache->sql_exists($safe_query_id))
 297          {
 298              return $cache->sql_rowseek($rownum, $safe_query_id);
 299          }
 300  
 301          return ($query_id) ? @mysqli_data_seek($query_id, $rownum) : false;
 302      }
 303  
 304      /**
 305       * {@inheritdoc}
 306       */
 307  	public function sql_last_inserted_id()
 308      {
 309          return ($this->db_connect_id) ? @mysqli_insert_id($this->db_connect_id) : false;
 310      }
 311  
 312      /**
 313      * {@inheritDoc}
 314      */
 315  	function sql_freeresult($query_id = false)
 316      {
 317          global $cache;
 318  
 319          if ($query_id === false)
 320          {
 321              $query_id = $this->query_result;
 322          }
 323  
 324          $safe_query_id = $this->clean_query_id($query_id);
 325          if ($cache && $cache->sql_exists($safe_query_id))
 326          {
 327              return $cache->sql_freeresult($safe_query_id);
 328          }
 329  
 330          if (!$query_id)
 331          {
 332              return false;
 333          }
 334  
 335          if ($query_id === true)
 336          {
 337              return true;
 338          }
 339  
 340          return mysqli_free_result($query_id);
 341      }
 342  
 343      /**
 344      * {@inheritDoc}
 345      */
 346  	function sql_escape($msg)
 347      {
 348          return @mysqli_real_escape_string($this->db_connect_id, $msg);
 349      }
 350  
 351      /**
 352      * return sql error array
 353      * @access private
 354      */
 355  	function _sql_error()
 356      {
 357          if ($this->db_connect_id)
 358          {
 359              $error = [
 360                  'message'    => $this->db_connect_id->error,
 361                  'code'        => $this->db_connect_id->errno,
 362              ];
 363          }
 364          else if (function_exists('mysqli_connect_error'))
 365          {
 366              $error = [
 367                  'message'    => $this->db_connect_id->connect_error,
 368                  'code'        => $this->db_connect_id->connect_errno,
 369              ];
 370          }
 371          else
 372          {
 373              $error = [
 374                  'message'    => $this->connect_error,
 375                  'code'        => '',
 376              ];
 377          }
 378  
 379          return $error;
 380      }
 381  
 382      /**
 383      * Close sql connection
 384      * @access private
 385      */
 386  	function _sql_close()
 387      {
 388          return @mysqli_close($this->db_connect_id);
 389      }
 390  
 391      /**
 392      * Build db-specific report
 393      * @access private
 394      */
 395  	function _sql_report($mode, $query = '')
 396      {
 397          static $test_prof;
 398  
 399          // current detection method, might just switch to see the existence of INFORMATION_SCHEMA.PROFILING
 400          if ($test_prof === null)
 401          {
 402              $test_prof = false;
 403              if (strpos(mysqli_get_server_info($this->db_connect_id), 'community') !== false)
 404              {
 405                  $ver = mysqli_get_server_version($this->db_connect_id);
 406                  if ($ver >= 50037 && $ver < 50100)
 407                  {
 408                      $test_prof = true;
 409                  }
 410              }
 411          }
 412  
 413          switch ($mode)
 414          {
 415              case 'start':
 416  
 417                  $explain_query = $query;
 418                  if (preg_match('/UPDATE ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
 419                  {
 420                      $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
 421                  }
 422                  else if (preg_match('/DELETE FROM ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
 423                  {
 424                      $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
 425                  }
 426  
 427                  if (preg_match('/^SELECT/', $explain_query))
 428                  {
 429                      $html_table = false;
 430  
 431                      // begin profiling
 432                      if ($test_prof)
 433                      {
 434                          @mysqli_query($this->db_connect_id, 'SET profiling = 1;');
 435                      }
 436  
 437                      if ($result = @mysqli_query($this->db_connect_id, "EXPLAIN $explain_query"))
 438                      {
 439                          while ($row = mysqli_fetch_assoc($result))
 440                          {
 441                              $html_table = $this->sql_report('add_select_row', $query, $html_table, $row);
 442                          }
 443                          mysqli_free_result($result);
 444                      }
 445  
 446                      if ($html_table)
 447                      {
 448                          $this->html_hold .= '</table>';
 449                      }
 450  
 451                      if ($test_prof)
 452                      {
 453                          $html_table = false;
 454  
 455                          // get the last profile
 456                          if ($result = @mysqli_query($this->db_connect_id, 'SHOW PROFILE ALL;'))
 457                          {
 458                              $this->html_hold .= '<br />';
 459                              while ($row = mysqli_fetch_assoc($result))
 460                              {
 461                                  // make <unknown> HTML safe
 462                                  if (!empty($row['Source_function']))
 463                                  {
 464                                      $row['Source_function'] = str_replace(array('<', '>'), array('&lt;', '&gt;'), $row['Source_function']);
 465                                  }
 466  
 467                                  // remove unsupported features
 468                                  foreach ($row as $key => $val)
 469                                  {
 470                                      if ($val === null)
 471                                      {
 472                                          unset($row[$key]);
 473                                      }
 474                                  }
 475                                  $html_table = $this->sql_report('add_select_row', $query, $html_table, $row);
 476                              }
 477                              mysqli_free_result($result);
 478                          }
 479  
 480                          if ($html_table)
 481                          {
 482                              $this->html_hold .= '</table>';
 483                          }
 484  
 485                          @mysqli_query($this->db_connect_id, 'SET profiling = 0;');
 486                      }
 487                  }
 488  
 489              break;
 490  
 491              case 'fromcache':
 492                  $endtime = explode(' ', microtime());
 493                  $endtime = $endtime[0] + $endtime[1];
 494  
 495                  $result = @mysqli_query($this->db_connect_id, $query);
 496                  if ($result)
 497                  {
 498                      while ($void = mysqli_fetch_assoc($result))
 499                      {
 500                          // Take the time spent on parsing rows into account
 501                      }
 502                      mysqli_free_result($result);
 503                  }
 504  
 505                  $splittime = explode(' ', microtime());
 506                  $splittime = $splittime[0] + $splittime[1];
 507  
 508                  $this->sql_report('record_fromcache', $query, $endtime, $splittime);
 509  
 510              break;
 511          }
 512      }
 513  
 514      /**
 515      * {@inheritDoc}
 516      */
 517  	function sql_quote($msg)
 518      {
 519          return '`' . $msg . '`';
 520      }
 521  }


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1