[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
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('<', '>'), $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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |