Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

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

database.php

Zuletzt modifiziert: 09.10.2024, 12:54 - Dateigröße: 10.72 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\install\helper;
015   
016  use phpbb\install\exception\invalid_dbms_exception;
017   
018  /**
019   * Database related general functionality for installer
020   */
021  class database
022  {
023      /**
024       * @var \phpbb\filesystem\filesystem_interface
025       */
026      protected $filesystem;
027   
028      /**
029       * @var string
030       */
031      protected $phpbb_root_path;
032   
033      /**
034       * @var array
035       */
036      protected $supported_dbms = array(
037          // Note: php 5.5 alpha 2 deprecated mysql.
038          // Keep mysqli before mysql in this list.
039          'mysqli'    => array(
040              'LABEL'            => 'MySQL with MySQLi Extension',
041              'SCHEMA'        => 'mysql_41',
042              'MODULE'        => 'mysqli',
043              'DELIM'            => ';',
044              'DRIVER'        => 'phpbb\db\driver\mysqli',
045              'AVAILABLE'        => true,
046              '2.0.x'            => true,
047          ),
048          'mysql'        => array(
049              'LABEL'            => 'MySQL',
050              'SCHEMA'        => 'mysql',
051              'MODULE'        => 'mysql',
052              'DELIM'            => ';',
053              'DRIVER'        => 'phpbb\db\driver\mysql',
054              'AVAILABLE'        => true,
055              '2.0.x'            => true,
056          ),
057          'mssql_odbc'=>    array(
058              'LABEL'            => 'MS SQL Server [ ODBC ]',
059              'SCHEMA'        => 'mssql',
060              'MODULE'        => 'odbc',
061              'DELIM'            => ';',
062              'DRIVER'        => 'phpbb\db\driver\mssql_odbc',
063              'AVAILABLE'        => true,
064              '2.0.x'            => true,
065          ),
066          'mssqlnative'        => array(
067              'LABEL'            => 'MS SQL Server 2005+ [ Native ]',
068              'SCHEMA'        => 'mssql',
069              'MODULE'        => 'sqlsrv',
070              'DELIM'            => ';',
071              'DRIVER'        => 'phpbb\db\driver\mssqlnative',
072              'AVAILABLE'        => true,
073              '2.0.x'            => false,
074          ),
075          'oracle'    =>    array(
076              'LABEL'            => 'Oracle',
077              'SCHEMA'        => 'oracle',
078              'MODULE'        => 'oci8',
079              'DELIM'            => '/',
080              'DRIVER'        => 'phpbb\db\driver\oracle',
081              'AVAILABLE'        => true,
082              '2.0.x'            => false,
083          ),
084          'postgres' => array(
085              'LABEL'            => 'PostgreSQL 8.3+',
086              'SCHEMA'        => 'postgres',
087              'MODULE'        => 'pgsql',
088              'DELIM'            => ';',
089              'DRIVER'        => 'phpbb\db\driver\postgres',
090              'AVAILABLE'        => true,
091              '2.0.x'            => true,
092          ),
093          'sqlite3'        => array(
094              'LABEL'            => 'SQLite3',
095              'SCHEMA'        => 'sqlite',
096              'MODULE'        => 'sqlite3',
097              'DELIM'            => ';',
098              'DRIVER'        => 'phpbb\db\driver\sqlite3',
099              'AVAILABLE'        => true,
100              '2.0.x'            => false,
101          ),
102      );
103   
104      /**
105       * Constructor
106       *
107       * @param \phpbb\filesystem\filesystem_interface    $filesystem            Filesystem interface
108       * @param string                                    $phpbb_root_path    Path to phpBB's root
109       */
110      public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path)
111      {
112          $this->filesystem        = $filesystem;
113          $this->phpbb_root_path    = $phpbb_root_path;
114      }
115   
116      /**
117       * Returns an array of available DBMS supported by phpBB
118       *
119       * If a DBMS is specified it will only return data for that DBMS
120       * and will load its extension if necessary.
121       *
122       * @param    mixed    $dbms                name of the DBMS that's info is required or false for all DBMS info
123       * @param    bool    $return_unavailable    set it to true if you expect unavailable but supported DBMS
124       *                                         returned as well
125       * @param    bool    $only_20x_options    set it to true if you only want to recover 2.0.x options
126       *
127       * @return    array    Array of available and supported DBMS
128       */
129      public function get_available_dbms($dbms = false, $return_unavailable = false, $only_20x_options = false)
130      {
131          $available_dbms = $this->supported_dbms;
132   
133          if ($dbms)
134          {
135              if (isset($this->supported_dbms[$dbms]))
136              {
137                  $available_dbms = array($dbms => $this->supported_dbms[$dbms]);
138              }
139              else
140              {
141                  return array();
142              }
143          }
144   
145          $any_dbms_available = false;
146          foreach ($available_dbms as $db_name => $db_array)
147          {
148              if ($only_20x_options && !$db_array['2.0.x'])
149              {
150                  if ($return_unavailable)
151                  {
152                      $available_dbms[$db_name]['AVAILABLE'] = false;
153                  }
154                  else
155                  {
156                      unset($available_dbms[$db_name]);
157                  }
158   
159                  continue;
160              }
161   
162              $dll = $db_array['MODULE'];
163              if (!@extension_loaded($dll))
164              {
165                  if ($return_unavailable)
166                  {
167                      $available_dbms[$db_name]['AVAILABLE'] = false;
168                  }
169                  else
170                  {
171                      unset($available_dbms[$db_name]);
172                  }
173   
174                  continue;
175              }
176   
177              $any_dbms_available = true;
178          }
179   
180          if ($return_unavailable)
181          {
182              $available_dbms['ANY_DB_SUPPORT'] = $any_dbms_available;
183          }
184   
185          return $available_dbms;
186      }
187   
188      /**
189       * Removes "/* style" as well as "# style" comments from $input.
190       *
191       * @param string $sql_query    Input string
192       *
193       * @return string Input string with comments removed
194       */
195      public function remove_comments($sql_query)
196      {
197          // Remove /* */ comments (http://ostermiller.org/findcomment.html)
198          $sql_query = preg_replace('#/\*(.|[\r\n])*?\*/#', "\n", $sql_query);
199   
200          // Remove # style comments
201          $sql_query = preg_replace('/\n{2,}/', "\n", preg_replace('/^#.*$/m', "\n", $sql_query));
202   
203          return $sql_query;
204      }
205   
206      /**
207       * split_sql_file() will split an uploaded sql file into single sql statements.
208       *
209       * Note: expects trim() to have already been run on $sql.
210       *
211       * @param    string    $sql        SQL statements
212       * @param    string    $delimiter    Delimiter between sql statements
213       *
214       * @return array Array of sql statements
215       */
216      public function split_sql_file($sql, $delimiter)
217      {
218          $sql = str_replace("\r" , '', $sql);
219          $data = preg_split('/' . preg_quote($delimiter, '/') . '$/m', $sql);
220   
221          $data = array_map('trim', $data);
222   
223          // The empty case
224          $end_data = end($data);
225   
226          if (empty($end_data))
227          {
228              unset($data[key($data)]);
229          }
230   
231          return $data;
232      }
233   
234      /**
235       * Validates table prefix
236       *
237       * @param string    $dbms            The selected dbms
238       * @param string    $table_prefix    The table prefix to validate
239       *
240       * @return bool|array    true if table prefix is valid, array of errors otherwise
241       *
242       * @throws \phpbb\install\exception\invalid_dbms_exception When $dbms is not a valid
243       */
244      public function validate_table_prefix($dbms, $table_prefix)
245      {
246          $errors = array();
247   
248          if (!preg_match('#^[a-zA-Z][a-zA-Z0-9_]*$#', $table_prefix))
249          {
250              $errors[] = array(
251                  'title' => 'INST_ERR_DB_INVALID_PREFIX',
252              );
253          }
254   
255          // Do dbms specific checks
256          $dbms_info = $this->get_available_dbms($dbms);
257          switch ($dbms_info[$dbms]['SCHEMA'])
258          {
259              case 'mysql':
260              case 'mysql_41':
261                  $prefix_length = 36;
262              break;
263              case 'mssql':
264                  $prefix_length = 90;
265              break;
266              case 'oracle':
267                  $prefix_length = 6;
268              break;
269              case 'postgres':
270                  $prefix_length = 36;
271              break;
272              case 'sqlite':
273                  $prefix_length = 200;
274              break;
275              default:
276                  throw new invalid_dbms_exception();
277              break;
278          }
279   
280          // Check the prefix length to ensure that index names are not too long
281          if (strlen($table_prefix) > $prefix_length)
282          {
283              $errors[] = array(
284                  'title' => array('INST_ERR_PREFIX_TOO_LONG', $prefix_length),
285              );
286          }
287   
288          return (empty($errors)) ? true : $errors;
289      }
290   
291      /**
292       * Check if the user provided database parameters are correct
293       *
294       * This function checks the database connection data and also checks for
295       * any other problems that could cause an error during the installation
296       * such as if there is any database table names conflicting.
297       *
298       * Note: The function assumes that $table_prefix has been already validated
299       * with validate_table_prefix().
300       *
301       * @param string    $dbms            Selected database type
302       * @param string    $dbhost            Database host address
303       * @param int        $dbport            Database port number
304       * @param string    $dbuser            Database username
305       * @param string    $dbpass            Database password
306       * @param string    $dbname            Database name
307       * @param string    $table_prefix    Database table prefix
308       *
309       * @return array|bool    Returns true if test is successful, array of errors otherwise
310       */
311      public function check_database_connection($dbms, $dbhost, $dbport, $dbuser, $dbpass, $dbname, $table_prefix)
312      {
313          $dbms_info = $this->get_available_dbms($dbms);
314          $dbms_info = $dbms_info[$dbms];
315          $errors = array();
316   
317          // Instantiate it and set return on error true
318          /** @var \phpbb\db\driver\driver_interface $db */
319          $db = new $dbms_info['DRIVER'];
320          $db->sql_return_on_error(true);
321   
322          // Check that we actually have a database name before going any further
323          if (!in_array($dbms_info['SCHEMA'], array('sqlite', 'oracle'), true) && $dbname === '')
324          {
325              $errors[] = array(
326                  'title' => 'INST_ERR_DB_NO_NAME',
327              );
328          }
329   
330          // Make sure we don't have a daft user who thinks having the SQLite database in the forum directory is a good idea
331          if ($dbms_info['SCHEMA'] === 'sqlite'
332              && stripos($this->filesystem->realpath($dbhost), $this->filesystem->realpath($this->phpbb_root_path) === 0))
333          {
334              $errors[] = array(
335                  'title' =>'INST_ERR_DB_FORUM_PATH',
336              );
337          }
338   
339          // Try to connect to db
340          if (is_array($db->sql_connect($dbhost, $dbuser, $dbpass, $dbname, $dbport, false, true)))
341          {
342              $db_error = $db->sql_error();
343              $errors[] = array(
344                  'title' => 'INST_ERR_DB_CONNECT',
345                  'description' => ($db_error['message']) ? utf8_convert_message($db_error['message']) : 'INST_ERR_DB_NO_ERROR',
346              );
347          }
348          else
349          {
350              // Check if there is any table name collisions
351              $temp_prefix = strtolower($table_prefix);
352              $table_ary = array(
353                  $temp_prefix . 'attachments',
354                  $temp_prefix . 'config',
355                  $temp_prefix . 'sessions',
356                  $temp_prefix . 'topics',
357                  $temp_prefix . 'users',
358              );
359   
360              $db_tools_factory = new \phpbb\db\tools\factory();
361              $db_tools = $db_tools_factory->get($db);
362              $tables = $db_tools->sql_list_tables();
363              $tables = array_map('strtolower', $tables);
364              $table_intersect = array_intersect($tables, $table_ary);
365   
366              if (sizeof($table_intersect))
367              {
368                  $errors[] = array(
369                      'title' => 'INST_ERR_PREFIX',
370                  );
371              }
372   
373              // Check if database version is supported
374              switch ($dbms)
375              {
376                  case 'mysqli':
377                      if (version_compare($db->sql_server_info(true), '4.1.3', '<'))
378                      {
379                          $errors[] = array(
380                              'title' => 'INST_ERR_DB_NO_MYSQLI',
381                          );
382                      }
383                  break;
384                  case 'sqlite3':
385                      if (version_compare($db->sql_server_info(true), '3.6.15', '<'))
386                      {
387                          $errors[] = array(
388                              'title' => 'INST_ERR_DB_NO_SQLITE3',
389                          );
390                      }
391                  break;
392                  case 'oracle':
393                      $sql = "SELECT *
394                          FROM NLS_DATABASE_PARAMETERS
395                          WHERE PARAMETER = 'NLS_RDBMS_VERSION'
396                              OR PARAMETER = 'NLS_CHARACTERSET'";
397                      $result = $db->sql_query($sql);
398   
399                      while ($row = $db->sql_fetchrow($result))
400                      {
401                          $stats[$row['parameter']] = $row['value'];
402                      }
403                      $db->sql_freeresult($result);
404   
405                      if (version_compare($stats['NLS_RDBMS_VERSION'], '9.2', '<') && $stats['NLS_CHARACTERSET'] !== 'UTF8')
406                      {
407                          $errors[] = array(
408                              'title' => 'INST_ERR_DB_NO_ORACLE',
409                          );
410                      }
411                  break;
412                  case 'postgres':
413                      $sql = "SHOW server_encoding;";
414                      $result = $db->sql_query($sql);
415                      $row = $db->sql_fetchrow($result);
416                      $db->sql_freeresult($result);
417   
418                      if ($row['server_encoding'] !== 'UNICODE' && $row['server_encoding'] !== 'UTF8')
419                      {
420                          $errors[] = array(
421                              'title' => 'INST_ERR_DB_NO_POSTGRES',
422                          );
423                      }
424                  break;
425              }
426          }
427   
428          return (empty($errors)) ? true : $errors;
429      }
430  }
431