Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

mysqli.php

Zuletzt modifiziert: 02.04.2025, 15:02 - Dateigröße: 11.13 KiB


001  <?php
002  /**
003  *
004  * This file is part of the phpBB Forum Software package.
005  *
006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
007  * @license GNU General Public License, version 2 (GPL-2.0)
008  *
009  * For full copyright and license information, please see
010  * the docs/CREDITS.txt file.
011  *
012  */
013   
014  namespace phpbb\db\driver;
015   
016  /**
017  * MySQLi Database Abstraction Layer
018  * mysqli-extension has to be compiled with:
019  * MySQL 4.1+ or MySQL 5.0+
020  */
021  class mysqli extends \phpbb\db\driver\mysql_base
022  {
023      var $multi_insert = true;
024      var $connect_error = '';
025   
026      /**
027      * {@inheritDoc}
028      */
029      function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
030      {
031          if (!function_exists('mysqli_connect'))
032          {
033              $this->connect_error = 'mysqli_connect function does not exist, is mysqli extension installed?';
034              return $this->sql_error('');
035          }
036   
037          $this->persistency = $persistency;
038          $this->user = $sqluser;
039   
040          // If persistent connection, set dbhost to localhost when empty and prepend it with 'p:' prefix
041          $this->server = ($this->persistency) ? 'p:' . (($sqlserver) ? $sqlserver : 'localhost') : $sqlserver;
042   
043          $this->dbname = $database;
044          $port = (!$port) ? null : $port;
045   
046          // If port is set and it is not numeric, most likely mysqli socket is set.
047          // Try to map it to the $socket parameter.
048          $socket = null;
049          if ($port)
050          {
051              if (is_numeric($port))
052              {
053                  $port = (int) $port;
054              }
055              else
056              {
057                  $socket = $port;
058                  $port = null;
059              }
060          }
061   
062          if (!$this->db_connect_id = mysqli_init())
063          {
064              $this->connect_error = 'Failed to initialize MySQLi object.';
065   
066          }
067          else if (!@mysqli_real_connect($this->db_connect_id, $this->server, $this->user, $sqlpassword, $this->dbname, $port, $socket, MYSQLI_CLIENT_FOUND_ROWS))
068          {
069              $this->connect_error = 'Failed to establish a connection to the MySQL database engine. Please ensure MySQL server is running and the database configuration parameters are correct.';
070          }
071   
072          if (!$this->connect_error && $this->db_connect_id && $this->dbname != '')
073          {
074              // Disable loading local files on client side
075              @mysqli_options($this->db_connect_id, MYSQLI_OPT_LOCAL_INFILE, false);
076   
077              /*
078               * As of PHP 8.1 MySQLi default error mode is set to MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT
079               * See https://wiki.php.net/rfc/mysqli_default_errmode
080               * Since phpBB implements own SQL errors handling, explicitly set it back to MYSQLI_REPORT_OFF
081               */
082              mysqli_report(MYSQLI_REPORT_OFF);
083   
084              @mysqli_query($this->db_connect_id, "SET NAMES 'utf8'");
085   
086              // enforce strict mode on databases that support it
087              if (version_compare($this->sql_server_info(true), '5.0.2', '>='))
088              {
089                  $result = @mysqli_query($this->db_connect_id, 'SELECT @@session.sql_mode AS sql_mode');
090                  if ($result)
091                  {
092                      $row = mysqli_fetch_assoc($result);
093                      mysqli_free_result($result);
094   
095                      $modes = array_map('trim', explode(',', $row['sql_mode']));
096                  }
097                  else
098                  {
099                      $modes = array();
100                  }
101   
102                  // TRADITIONAL includes STRICT_ALL_TABLES and STRICT_TRANS_TABLES
103                  if (!in_array('TRADITIONAL', $modes))
104                  {
105                      if (!in_array('STRICT_ALL_TABLES', $modes))
106                      {
107                          $modes[] = 'STRICT_ALL_TABLES';
108                      }
109   
110                      if (!in_array('STRICT_TRANS_TABLES', $modes))
111                      {
112                          $modes[] = 'STRICT_TRANS_TABLES';
113                      }
114                  }
115   
116                  $mode = implode(',', $modes);
117                  @mysqli_query($this->db_connect_id, "SET SESSION sql_mode='{$mode}'");
118              }
119              return $this->db_connect_id;
120          }
121   
122          return $this->sql_error('');
123      }
124   
125      /**
126      * {@inheritDoc}
127      */
128      function sql_server_info($raw = false, $use_cache = true)
129      {
130          global $cache;
131   
132          if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('mysqli_version')) === false)
133          {
134              $result = @mysqli_query($this->db_connect_id, 'SELECT VERSION() AS version');
135              if ($result)
136              {
137                  $row = mysqli_fetch_assoc($result);
138                  mysqli_free_result($result);
139   
140                  $this->sql_server_version = $row['version'];
141   
142                  if (!empty($cache) && $use_cache)
143                  {
144                      $cache->put('mysqli_version', $this->sql_server_version);
145                  }
146              }
147          }
148   
149          return ($raw) ? $this->sql_server_version : 'MySQL(i) ' . $this->sql_server_version;
150      }
151   
152      /**
153      * SQL Transaction
154      * @access private
155      */
156      function _sql_transaction($status = 'begin')
157      {
158          switch ($status)
159          {
160              case 'begin':
161                  @mysqli_autocommit($this->db_connect_id, false);
162                  $result = @mysqli_begin_transaction($this->db_connect_id);
163                  return $result;
164              break;
165   
166              case 'commit':
167                  $result = @mysqli_commit($this->db_connect_id);
168                  @mysqli_autocommit($this->db_connect_id, true);
169                  return $result;
170              break;
171   
172              case 'rollback':
173                  $result = @mysqli_rollback($this->db_connect_id);
174                  @mysqli_autocommit($this->db_connect_id, true);
175                  return $result;
176              break;
177          }
178   
179          return true;
180      }
181   
182      /**
183      * {@inheritDoc}
184      */
185      function sql_query($query = '', $cache_ttl = 0)
186      {
187          if ($query != '')
188          {
189              global $cache;
190   
191              if ($this->debug_sql_explain)
192              {
193                  $this->sql_report('start', $query);
194              }
195              else if ($this->debug_load_time)
196              {
197                  $this->curtime = microtime(true);
198              }
199   
200              $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false;
201              $this->sql_add_num_queries($this->query_result);
202   
203              if ($this->query_result === false)
204              {
205                  try
206                  {
207                      $this->query_result = @mysqli_query($this->db_connect_id, $query);
208                  }
209                  catch (\Error $e)
210                  {
211                      // Do nothing as SQL driver will report the error
212                  }
213   
214                  if ($this->query_result === false)
215                  {
216                      $this->sql_error($query);
217                  }
218   
219                  if ($this->debug_sql_explain)
220                  {
221                      $this->sql_report('stop', $query);
222                  }
223                  else if ($this->debug_load_time)
224                  {
225                      $this->sql_time += microtime(true) - $this->curtime;
226                  }
227   
228                  if (!$this->query_result)
229                  {
230                      return false;
231                  }
232   
233                  if ($cache && $cache_ttl)
234                  {
235                      $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl);
236                  }
237              }
238              else if ($this->debug_sql_explain)
239              {
240                  $this->sql_report('fromcache', $query);
241              }
242          }
243          else
244          {
245              return false;
246          }
247   
248          return $this->query_result;
249      }
250   
251      /**
252      * {@inheritDoc}
253      */
254      function sql_affectedrows()
255      {
256          return ($this->db_connect_id) ? @mysqli_affected_rows($this->db_connect_id) : false;
257      }
258   
259      /**
260      * {@inheritDoc}
261      */
262      function sql_fetchrow($query_id = false)
263      {
264          global $cache;
265   
266          if ($query_id === false)
267          {
268              $query_id = $this->query_result;
269          }
270   
271          $safe_query_id = $this->clean_query_id($query_id);
272          if ($cache && $cache->sql_exists($safe_query_id))
273          {
274              return $cache->sql_fetchrow($safe_query_id);
275          }
276   
277          if ($query_id)
278          {
279              $result = mysqli_fetch_assoc($query_id);
280              return $result !== null ? $result : false;
281          }
282   
283          return false;
284      }
285   
286      /**
287      * {@inheritDoc}
288      */
289      function sql_rowseek($rownum, &$query_id)
290      {
291          global $cache;
292   
293          if ($query_id === false)
294          {
295              $query_id = $this->query_result;
296          }
297   
298          $safe_query_id = $this->clean_query_id($query_id);
299          if ($cache && $cache->sql_exists($safe_query_id))
300          {
301              return $cache->sql_rowseek($rownum, $safe_query_id);
302          }
303   
304          return ($query_id) ? @mysqli_data_seek($query_id, $rownum) : false;
305      }
306   
307      /**
308       * {@inheritdoc}
309       */
310      public function sql_last_inserted_id()
311      {
312          return ($this->db_connect_id) ? @mysqli_insert_id($this->db_connect_id) : false;
313      }
314   
315      /**
316      * {@inheritDoc}
317      */
318      function sql_freeresult($query_id = false)
319      {
320          global $cache;
321   
322          if ($query_id === false)
323          {
324              $query_id = $this->query_result;
325          }
326   
327          $safe_query_id = $this->clean_query_id($query_id);
328          if ($cache && $cache->sql_exists($safe_query_id))
329          {
330              return $cache->sql_freeresult($safe_query_id);
331          }
332   
333          if (!$query_id)
334          {
335              return false;
336          }
337   
338          if ($query_id === true)
339          {
340              return true;
341          }
342   
343          return mysqli_free_result($query_id);
344      }
345   
346      /**
347      * {@inheritDoc}
348      */
349      function sql_escape($msg)
350      {
351          return @mysqli_real_escape_string($this->db_connect_id, $msg);
352      }
353   
354      /**
355      * return sql error array
356      * @access private
357      */
358      function _sql_error()
359      {
360          if ($this->db_connect_id)
361          {
362              $error = [
363                  'message'    => $this->db_connect_id->connect_error ?: $this->db_connect_id->error,
364                  'code'        => $this->db_connect_id->connect_errno ?: $this->db_connect_id->errno,
365              ];
366          }
367          else
368          {
369              $error = [
370                  'message'    => $this->connect_error,
371                  'code'        => '',
372              ];
373          }
374   
375          return $error;
376      }
377   
378      /**
379      * Close sql connection
380      * @access private
381      */
382      function _sql_close()
383      {
384          return @mysqli_close($this->db_connect_id);
385      }
386   
387      /**
388      * Build db-specific report
389      * @access private
390      */
391      function _sql_report($mode, $query = '')
392      {
393          static $test_prof;
394   
395          // current detection method, might just switch to see the existence of INFORMATION_SCHEMA.PROFILING
396          if ($test_prof === null)
397          {
398              $test_prof = false;
399              if (strpos(mysqli_get_server_info($this->db_connect_id), 'community') !== false)
400              {
401                  $ver = mysqli_get_server_version($this->db_connect_id);
402                  if ($ver >= 50037 && $ver < 50100)
403                  {
404                      $test_prof = true;
405                  }
406              }
407          }
408   
409          switch ($mode)
410          {
411              case 'start':
412   
413                  $explain_query = $query;
414                  if (preg_match('/UPDATE ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
415                  {
416                      $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
417                  }
418                  else if (preg_match('/DELETE FROM ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
419                  {
420                      $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
421                  }
422   
423                  if (preg_match('/^SELECT/', $explain_query))
424                  {
425                      $html_table = false;
426   
427                      // begin profiling
428                      if ($test_prof)
429                      {
430                          @mysqli_query($this->db_connect_id, 'SET profiling = 1;');
431                      }
432   
433                      if ($result = @mysqli_query($this->db_connect_id, "EXPLAIN $explain_query"))
434                      {
435                          while ($row = mysqli_fetch_assoc($result))
436                          {
437                              $html_table = $this->sql_report('add_select_row', $query, $html_table, $row);
438                          }
439                          mysqli_free_result($result);
440                      }
441   
442                      if ($html_table)
443                      {
444                          $this->html_hold .= '</table>';
445                      }
446   
447                      if ($test_prof)
448                      {
449                          $html_table = false;
450   
451                          // get the last profile
452                          if ($result = @mysqli_query($this->db_connect_id, 'SHOW PROFILE ALL;'))
453                          {
454                              $this->html_hold .= '<br />';
455                              while ($row = mysqli_fetch_assoc($result))
456                              {
457                                  // make <unknown> HTML safe
458                                  if (!empty($row['Source_function']))
459                                  {
460                                      $row['Source_function'] = str_replace(array('<', '>'), array('&lt;', '&gt;'), $row['Source_function']);
461                                  }
462   
463                                  // remove unsupported features
464                                  foreach ($row as $key => $val)
465                                  {
466                                      if ($val === null)
467                                      {
468                                          unset($row[$key]);
469                                      }
470                                  }
471                                  $html_table = $this->sql_report('add_select_row', $query, $html_table, $row);
472                              }
473                              mysqli_free_result($result);
474                          }
475   
476                          if ($html_table)
477                          {
478                              $this->html_hold .= '</table>';
479                          }
480   
481                          @mysqli_query($this->db_connect_id, 'SET profiling = 0;');
482                      }
483                  }
484   
485              break;
486   
487              case 'fromcache':
488                  $endtime = explode(' ', microtime());
489                  $endtime = $endtime[0] + $endtime[1];
490   
491                  $result = @mysqli_query($this->db_connect_id, $query);
492                  if ($result)
493                  {
494                      while ($void = mysqli_fetch_assoc($result))
495                      {
496                          // Take the time spent on parsing rows into account
497                      }
498                      mysqli_free_result($result);
499                  }
500   
501                  $splittime = explode(' ', microtime());
502                  $splittime = $splittime[0] + $splittime[1];
503   
504                  $this->sql_report('record_fromcache', $query, $endtime, $splittime);
505   
506              break;
507          }
508      }
509   
510      /**
511      * {@inheritDoc}
512      */
513      function sql_quote($msg)
514      {
515          return '`' . $msg . '`';
516      }
517  }
518