[ Index ]

PHP Cross Reference of MyBB 1.8.27

title

Body

[close]

/inc/ -> db_mysql_pdo.php (source)

   1  <?php
   2  /**
   3   * MyBB 1.8
   4   * Copyright 2020 MyBB Group, All Rights Reserved
   5   *
   6   * Website: http://www.mybb.com
   7   * License: http://www.mybb.com/about/license
   8   */
   9  
  10  class MysqlPdoDbDriver extends AbstractPdoDbDriver
  11  {
  12      /**
  13       * Explanation of a query.
  14       *
  15       * @var string
  16       */
  17      public $explain = '';
  18  
  19  	protected function getDsn($hostname, $db, $port, $encoding)
  20      {
  21          $dsn = "mysql:host={$hostname};dbname={$db}";
  22  
  23          if ($port !== null) {
  24              $dsn .= ";port={$port}";
  25          }
  26  
  27          if (!empty($encoding)) {
  28              $dsn .= ";charset={$encoding}";
  29          }
  30  
  31          return $dsn;
  32      }
  33  
  34  	function explain_query($string, $qtime)
  35      {
  36          global $plugins;
  37  
  38          $duration = format_time_duration($qtime);
  39          $queryText = htmlspecialchars_uni($string);
  40  
  41          $debug_extra = '';
  42          if ($plugins->current_hook) {
  43              $debug_extra = <<<HTML
  44  <div style="float_right">(Plugin Hook: {$plugins->current_hook})</div>
  45  HTML;
  46          }
  47  
  48          if (preg_match('/^\\s*SELECT\\b/i', $string) === 1) {
  49              $query = $this->current_link->query("EXPLAIN {$string}");
  50  
  51              $this->explain .= <<<HTML
  52  <table style="background-color: #666;" width="95%" cellpadding="4" cellspacing="1" align="center">
  53      <tr>
  54          <td colspan="8" style="background-color: #ccc;">
  55              {$debug_extra}<div><strong>#{$this->query_count} - Select Query</strong></div>
  56          </td>
  57      </tr>
  58      <tr>
  59          <td colspan="8" style="background-color: #fefefe;">
  60              <span style="font-family: Courier; font-size: 14px;">{$queryText}</span>
  61          </td>
  62      </tr>
  63      <tr style="background-color: #efefef">
  64          <td><strong>Table</strong></td>
  65          <td><strong>Type</strong></td>
  66          <td><strong>Possible Keys</strong></td>
  67          <td><strong>Key</strong></td>
  68          <td><strong>Key Length</strong></td>
  69          <td><strong>Ref</strong></td>
  70          <td><strong>Rows</strong></td>
  71          <td><strong>Extra</strong></td>
  72      </tr>
  73  HTML;
  74  
  75              while ($table = $query->fetch(PDO::FETCH_ASSOC)) {
  76                  $this->explain .= <<<HTML
  77  <tr bgcolor="#ffffff">
  78      <td>{$table['table']}</td>
  79      <td>{$table['type']}</td>
  80      <td>{$table['possible_keys']}</td>
  81      <td>{$table['key']}</td>
  82      <td>{$table['key_len']}</td>
  83      <td>{$table['ref']}</td>
  84      <td>{$table['rows']}</td>
  85      <td>{$table['Extra']}</td>
  86  </tr>
  87  HTML;
  88              }
  89  
  90              $this->explain .= <<<HTML
  91  <tr>
  92      <td colspan="8" style="background-color: #fff;">
  93          Query Time: {$duration}
  94      </td>
  95  </tr>
  96  </table>
  97  <br />
  98  HTML;
  99          } else {
 100              $this->explain .= <<<HTML
 101  <table style="background-color: #666;" width="95%" cellpadding="4" cellspacing="1" align="center">
 102      <tr>
 103          <td style="background-color: #ccc;">
 104              {$debug_extra}<div><strong>#{$this->query_count} - Write Query</strong></div>
 105          </td>
 106      </tr>
 107      <tr style="background-color: #fefefe;">
 108          <td><span style="font-family: Courier; font-size: 14px;">{$queryText}</span></td>
 109      </tr>
 110      <tr>
 111          <td bgcolor="#ffffff">Query Time: {$duration}</td>
 112      </tr>
 113  </table>
 114  <br/>
 115  HTML;
 116          }
 117  
 118          $this->querylist[$this->query_count]['query'] = $string;
 119          $this->querylist[$this->query_count]['time'] = $qtime;
 120      }
 121  
 122  	public function list_tables($database, $prefix = '')
 123      {
 124          if ($prefix) {
 125              if (version_compare($this->get_version(), '5.0.2', '>=')) {
 126                  $query = $this->query("SHOW FULL TABLES FROM `{$database}` WHERE table_type = 'BASE TABLE' AND `Tables_in_{$database}` LIKE '".$this->escape_string($prefix)."%'");
 127              } else {
 128                  $query = $this->query("SHOW TABLES FROM `{$database}` LIKE '{$this->escape_string($prefix)}%'");
 129              }
 130          } else {
 131              if (version_compare($this->get_version(), '5.0.2', '>=')) {
 132                  $query = $this->query("SHOW FULL TABLES FROM `{$database}` WHERE table_type = 'BASE TABLE'");
 133              } else {
 134                  $query = $this->query("SHOW TABLES FROM `{$database}`");
 135              }
 136          }
 137  
 138          return $query->fetchAll(PDO::FETCH_COLUMN, 0);
 139      }
 140  
 141  	public function table_exists($table)
 142      {
 143          // Execute on master server to ensure if we've just created a table that we get the correct result
 144          if (version_compare($this->get_version(), '5.0.2', '>=')) {
 145              $query = $this->query("SHOW FULL TABLES FROM `{$this->database}` WHERE table_type = 'BASE TABLE' AND `Tables_in_{$this->database}` = '{$this->table_prefix}{$table}'");
 146          } else {
 147              $query = $this->query("SHOW TABLES LIKE '{$this->table_prefix}{$table}'");
 148          }
 149  
 150          $count = 0;
 151          while ($row = $this->fetch_array($query)) {
 152              $count++;
 153          }
 154  
 155          return $count > 0;
 156      }
 157  
 158  	public function field_exists($field, $table)
 159      {
 160          $query = $this->write_query("
 161              SHOW COLUMNS
 162              FROM {$this->table_prefix}{$table}
 163              LIKE '{$field}'
 164          ");
 165  
 166          $exists = $this->num_rows($query);
 167  
 168          return $exists > 0;
 169      }
 170  
 171  	public function simple_select($table, $fields = "*", $conditions = "", $options = array())
 172      {
 173          $query = "SELECT {$fields} FROM {$this->table_prefix}{$table}";
 174  
 175          if (!empty($conditions)) {
 176              $query .= " WHERE {$conditions}";
 177          }
 178  
 179          if (isset($options['group_by'])) {
 180              $query .= " GROUP BY {$options['group_by']}";
 181          }
 182  
 183          if (isset($options['order_by'])) {
 184              $query .= " ORDER BY {$options['order_by']}";
 185  
 186              if (isset($options['order_dir'])) {
 187                  $query .= " ".my_strtoupper($options['order_dir']);
 188              }
 189          }
 190  
 191          if (isset($options['limit_start']) && isset($options['limit'])) {
 192              $query .= " LIMIT {$options['limit_start']}, {$options['limit']}";
 193          }
 194          else if (isset($options['limit'])) {
 195              $query .= " LIMIT {$options['limit']}";
 196          }
 197  
 198          return $this->query($query);
 199      }
 200  
 201  	public function insert_query($table, $array)
 202      {
 203          global $mybb;
 204  
 205          if (!is_array($array)) {
 206              return false;
 207          }
 208  
 209          foreach ($array as $field => $value) {
 210              if(isset($mybb->binary_fields[$table][$field]) && $mybb->binary_fields[$table][$field]) {
 211                  if ($value[0] != 'X') { // Not escaped?
 212                      $value = $this->escape_binary($value);
 213                  }
 214  
 215                  $array[$field] = $value;
 216              } else {
 217                  $array[$field] = $this->quote_val($value);
 218              }
 219          }
 220  
 221          $fields = "`".implode("`,`", array_keys($array))."`";
 222  
 223          $values = implode(",", $array);
 224  
 225          $this->write_query("
 226              INSERT
 227              INTO {$this->table_prefix}{$table} ({$fields})
 228              VALUES ({$values})
 229          ");
 230  
 231          return $this->insert_id();
 232      }
 233  
 234  	public function insert_query_multiple($table, $array)
 235      {
 236          global $mybb;
 237  
 238          if (!is_array($array)) {
 239              return;
 240          }
 241  
 242          // Field names
 243          $fields = array_keys($array[0]);
 244          $fields = "`".implode("`,`", $fields)."`";
 245  
 246          $insert_rows = array();
 247          foreach ($array as $values) {
 248              foreach ($values as $field => $value) {
 249                  if (isset($mybb->binary_fields[$table][$field]) && $mybb->binary_fields[$table][$field]) {
 250                      if($value[0] != 'X') { // Not escaped?
 251                          $value = $this->escape_binary($value);
 252                      }
 253  
 254                      $values[$field] = $value;
 255                  } else {
 256                      $values[$field] = $this->quote_val($value);
 257                  }
 258              }
 259  
 260              $insert_rows[] = "(".implode(",", $values).")";
 261          }
 262  
 263          $insert_rows = implode(", ", $insert_rows);
 264  
 265          $this->write_query("
 266              INSERT
 267              INTO {$this->table_prefix}{$table} ({$fields})
 268              VALUES {$insert_rows}
 269          ");
 270      }
 271  
 272  	public function update_query($table, $array, $where = "", $limit = "", $no_quote = false)
 273      {
 274          global $mybb;
 275  
 276          if (!is_array($array)) {
 277              return false;
 278          }
 279  
 280          $comma = "";
 281          $query = "";
 282          $quote = "'";
 283  
 284          if ($no_quote == true) {
 285              $quote = "";
 286          }
 287  
 288          foreach ($array as $field => $value) {
 289              if (isset($mybb->binary_fields[$table][$field]) && $mybb->binary_fields[$table][$field]) {
 290                  if($value[0] != 'X') { // Not escaped?
 291                      $value = $this->escape_binary($value);
 292                  }
 293  
 294                  $query .= "{$comma}`{$field}`={$value}";
 295              } else {
 296                  $quoted_value = $this->quote_val($value, $quote);
 297  
 298                  $query .= "{$comma}`{$field}`={$quoted_value}";
 299              }
 300  
 301              $comma = ', ';
 302          }
 303  
 304          if (!empty($where)) {
 305              $query .= " WHERE {$where}";
 306          }
 307  
 308          if (!empty($limit)) {
 309              $query .= " LIMIT {$limit}";
 310          }
 311  
 312          return $this->write_query("
 313              UPDATE {$this->table_prefix}{$table}
 314              SET {$query}
 315          ");
 316      }
 317  
 318  	public function delete_query($table, $where = "", $limit = "")
 319      {
 320          $query = "";
 321          if (!empty($where)) {
 322              $query .= " WHERE {$where}";
 323          }
 324  
 325          if (!empty($limit)) {
 326              $query .= " LIMIT {$limit}";
 327          }
 328  
 329          return $this->write_query("DELETE FROM {$this->table_prefix}{$table} {$query}");
 330      }
 331  
 332  	public function optimize_table($table)
 333      {
 334          $this->write_query("OPTIMIZE TABLE {$this->table_prefix}{$table}");
 335      }
 336  
 337  	public function analyze_table($table)
 338      {
 339          $this->write_query("ANALYZE TABLE {$this->table_prefix}{$table}");
 340      }
 341  
 342  	public function show_create_table($table)
 343      {
 344          $query = $this->write_query("SHOW CREATE TABLE {$this->table_prefix}{$table}");
 345          $structure = $this->fetch_array($query);
 346  
 347          return $structure['Create Table'];
 348      }
 349  
 350  	public function show_fields_from($table)
 351      {
 352          $query = $this->write_query("SHOW FIELDS FROM {$this->table_prefix}{$table}");
 353  
 354          $field_info = array();
 355          while ($field = $this->fetch_array($query)) {
 356              $field_info[] = $field;
 357          }
 358  
 359          return $field_info;
 360      }
 361  
 362  	public function is_fulltext($table, $index = "")
 363      {
 364          $structure = $this->show_create_table($table);
 365          if ($index != "") {
 366              if(preg_match("#FULLTEXT KEY (`?){$index}(`?)#i", $structure)) {
 367                  return true;
 368              }
 369  
 370              return false;
 371          }
 372  
 373          if (preg_match('#FULLTEXT KEY#i', $structure)) {
 374              return true;
 375          }
 376  
 377          return false;
 378      }
 379  
 380  	public function supports_fulltext($table)
 381      {
 382          $version = $this->get_version();
 383          $query = $this->write_query("SHOW TABLE STATUS LIKE '{$this->table_prefix}$table'");
 384          $status = $this->fetch_array($query);
 385          $table_type = my_strtoupper($status['Engine']);
 386  
 387          if (version_compare($version, '3.23.23', '>=') && ($table_type == 'MYISAM' || $table_type == 'ARIA')) {
 388              return true;
 389          } else if (version_compare($version, '5.6', '>=') && $table_type == 'INNODB') {
 390              return true;
 391          }
 392  
 393          return false;
 394      }
 395  
 396  	public function index_exists($table, $index)
 397      {
 398          $index_exists = false;
 399          $query = $this->write_query("SHOW INDEX FROM {$this->table_prefix}{$table}");
 400          while ($ukey = $this->fetch_array($query)) {
 401              if ($ukey['Key_name'] == $index) {
 402                  $index_exists = true;
 403                  break;
 404              }
 405          }
 406  
 407          return $index_exists;
 408      }
 409  
 410  	public function supports_fulltext_boolean($table)
 411      {
 412          $version = $this->get_version();
 413          $supports_fulltext = $this->supports_fulltext($table);
 414          if (version_compare($version, '4.0.1', '>=') && $supports_fulltext == true) {
 415              return true;
 416          }
 417  
 418          return false;
 419      }
 420  
 421  	public function create_fulltext_index($table, $column, $name = "")
 422      {
 423          $this->write_query("ALTER TABLE {$this->table_prefix}{$table} ADD FULLTEXT {$name} ({$column})");
 424      }
 425  
 426  	public function drop_index($table, $name)
 427      {
 428          $this->write_query("ALTER TABLE {$this->table_prefix}{$table} DROP INDEX {$name}");
 429      }
 430  
 431  	public function drop_table($table, $hard = false, $table_prefix = true)
 432      {
 433          if ($table_prefix == false) {
 434              $table_prefix = "";
 435          } else {
 436              $table_prefix = $this->table_prefix;
 437          }
 438  
 439          if ($hard == false) {
 440              $this->write_query("DROP TABLE IF EXISTS {$table_prefix}{$table}");
 441          } else {
 442              $this->write_query("DROP TABLE {$table_prefix}{$table}");
 443          }
 444      }
 445  
 446  	public function rename_table($old_table, $new_table, $table_prefix = true)
 447      {
 448          if ($table_prefix == false) {
 449              $table_prefix = "";
 450          } else {
 451              $table_prefix = $this->table_prefix;
 452          }
 453  
 454          return $this->write_query("RENAME TABLE {$table_prefix}{$old_table} TO {$table_prefix}{$new_table}");
 455      }
 456  
 457  	public function replace_query($table, $replacements = array(), $default_field = "", $insert_id = true)
 458      {
 459          global $mybb;
 460  
 461          $values = '';
 462          $comma = '';
 463  
 464          foreach ($replacements as $column => $value) {
 465              if (isset($mybb->binary_fields[$table][$column]) && $mybb->binary_fields[$table][$column]) {
 466                  if ($value[0] != 'X') { // Not escaped?
 467                      $value = $this->escape_binary($value);
 468                  }
 469  
 470                  $values .= $comma."`".$column."`=".$value;
 471              } else {
 472                  $values .= $comma."`".$column."`=".$this->quote_val($value);
 473              }
 474  
 475              $comma = ',';
 476          }
 477  
 478          if (empty($replacements)) {
 479              return false;
 480          }
 481  
 482          return $this->write_query("REPLACE INTO {$this->table_prefix}{$table} SET {$values}");
 483      }
 484  
 485  	public function drop_column($table, $column)
 486      {
 487          $column = trim($column, '`');
 488  
 489          return $this->write_query("ALTER TABLE {$this->table_prefix}{$table} DROP `{$column}`");
 490      }
 491  
 492  	public function add_column($table, $column, $definition)
 493      {
 494          $column = trim($column, '`');
 495  
 496          return $this->write_query("ALTER TABLE {$this->table_prefix}{$table} ADD `{$column}` {$definition}");
 497      }
 498  
 499  	public function modify_column($table, $column, $new_definition, $new_not_null = false, $new_default_value = false)
 500      {
 501          $column = trim($column, '`');
 502  
 503          if ($new_not_null !== false) {
 504              if (strtolower($new_not_null) == "set") {
 505                  $not_null = "NOT NULL";
 506              } else {
 507                  $not_null = "NULL";
 508              }
 509          } else {
 510              $not_null = '';
 511          }
 512  
 513          if ($new_default_value !== false) {
 514              $default = "DEFAULT ".$new_default_value;
 515          }
 516          else
 517          {
 518              $default = '';
 519          }
 520  
 521          return (bool)$this->write_query("ALTER TABLE {$this->table_prefix}{$table} MODIFY `{$column}` {$new_definition} {$not_null} {$default}");
 522      }
 523  
 524  	public function rename_column($table, $old_column, $new_column, $new_definition, $new_not_null = false, $new_default_value = false)
 525      {
 526          $old_column = trim($old_column, '`');
 527          $new_column = trim($new_column, '`');
 528  
 529          if ($new_not_null !== false) {
 530              if(strtolower($new_not_null) == "set") {
 531                  $not_null = "NOT NULL";
 532              } else {
 533                  $not_null = "NULL";
 534              }
 535          } else {
 536              $not_null = '';
 537          }
 538  
 539          if ($new_default_value !== false) {
 540              $default = "DEFAULT ".$new_default_value;
 541          } else {
 542              $default = '';
 543          }
 544  
 545          return (bool)$this->write_query("ALTER TABLE {$this->table_prefix}{$table} CHANGE `{$old_column}` `{$new_column}` {$new_definition} {$not_null} {$default}");
 546      }
 547  
 548  	public function fetch_size($table = '')
 549      {
 550          if ($table != '') {
 551              $query = $this->query("SHOW TABLE STATUS LIKE '{$this->table_prefix}{$table}'");
 552          } else {
 553              $query = $this->query("SHOW TABLE STATUS");
 554          }
 555  
 556          $total = 0;
 557          while ($table = $this->fetch_array($query)) {
 558              $total += $table['Data_length'] + $table['Index_length'];
 559          }
 560  
 561          return $total;
 562      }
 563  
 564  	public function fetch_db_charsets()
 565      {
 566          if ($this->write_link && version_compare($this->get_version(), "4.1", "<")) {
 567              return false;
 568          }
 569  
 570          return array(
 571              'big5' => 'Big5 Traditional Chinese',
 572              'dec8' => 'DEC West European',
 573              'cp850' => 'DOS West European',
 574              'hp8' => 'HP West European',
 575              'koi8r' => 'KOI8-R Relcom Russian',
 576              'latin1' => 'ISO 8859-1 Latin 1',
 577              'latin2' => 'ISO 8859-2 Central European',
 578              'swe7' => '7bit Swedish',
 579              'ascii' => 'US ASCII',
 580              'ujis' => 'EUC-JP Japanese',
 581              'sjis' => 'Shift-JIS Japanese',
 582              'hebrew' => 'ISO 8859-8 Hebrew',
 583              'tis620' => 'TIS620 Thai',
 584              'euckr' => 'EUC-KR Korean',
 585              'koi8u' => 'KOI8-U Ukrainian',
 586              'gb2312' => 'GB2312 Simplified Chinese',
 587              'greek' => 'ISO 8859-7 Greek',
 588              'cp1250' => 'Windows Central European',
 589              'gbk' => 'GBK Simplified Chinese',
 590              'latin5' => 'ISO 8859-9 Turkish',
 591              'armscii8' => 'ARMSCII-8 Armenian',
 592              'utf8' => 'UTF-8 Unicode',
 593              'utf8mb4' => '4-Byte UTF-8 Unicode (requires MySQL 5.5.3 or above)',
 594              'ucs2' => 'UCS-2 Unicode',
 595              'cp866' => 'DOS Russian',
 596              'keybcs2' => 'DOS Kamenicky Czech-Slovak',
 597              'macce' => 'Mac Central European',
 598              'macroman' => 'Mac West European',
 599              'cp852' => 'DOS Central European',
 600              'latin7' => 'ISO 8859-13 Baltic',
 601              'cp1251' => 'Windows Cyrillic',
 602              'cp1256' => 'Windows Arabic',
 603              'cp1257' => 'Windows Baltic',
 604              'geostd8' => 'GEOSTD8 Georgian',
 605              'cp932' => 'SJIS for Windows Japanese',
 606              'eucjpms' => 'UJIS for Windows Japanese',
 607          );
 608      }
 609  
 610  	public function fetch_charset_collation($charset)
 611      {
 612          $collations = array(
 613              'big5' => 'big5_chinese_ci',
 614              'dec8' => 'dec8_swedish_ci',
 615              'cp850' => 'cp850_general_ci',
 616              'hp8' => 'hp8_english_ci',
 617              'koi8r' => 'koi8r_general_ci',
 618              'latin1' => 'latin1_swedish_ci',
 619              'latin2' => 'latin2_general_ci',
 620              'swe7' => 'swe7_swedish_ci',
 621              'ascii' => 'ascii_general_ci',
 622              'ujis' => 'ujis_japanese_ci',
 623              'sjis' => 'sjis_japanese_ci',
 624              'hebrew' => 'hebrew_general_ci',
 625              'tis620' => 'tis620_thai_ci',
 626              'euckr' => 'euckr_korean_ci',
 627              'koi8u' => 'koi8u_general_ci',
 628              'gb2312' => 'gb2312_chinese_ci',
 629              'greek' => 'greek_general_ci',
 630              'cp1250' => 'cp1250_general_ci',
 631              'gbk' => 'gbk_chinese_ci',
 632              'latin5' => 'latin5_turkish_ci',
 633              'armscii8' => 'armscii8_general_ci',
 634              'utf8' => 'utf8_general_ci',
 635              'utf8mb4' => 'utf8mb4_general_ci',
 636              'ucs2' => 'ucs2_general_ci',
 637              'cp866' => 'cp866_general_ci',
 638              'keybcs2' => 'keybcs2_general_ci',
 639              'macce' => 'macce_general_ci',
 640              'macroman' => 'macroman_general_ci',
 641              'cp852' => 'cp852_general_ci',
 642              'latin7' => 'latin7_general_ci',
 643              'cp1251' => 'cp1251_general_ci',
 644              'cp1256' => 'cp1256_general_ci',
 645              'cp1257' => 'cp1257_general_ci',
 646              'geostd8' => 'geostd8_general_ci',
 647              'cp932' => 'cp932_japanese_ci',
 648              'eucjpms' => 'eucjpms_japanese_ci',
 649          );
 650  
 651          if (isset($collations[$charset])) {
 652              return $collations[$charset];
 653          }
 654  
 655          return false;
 656      }
 657  
 658  	public function build_create_table_collation()
 659      {
 660          if (!$this->db_encoding) {
 661              return '';
 662          }
 663  
 664          $collation = $this->fetch_charset_collation($this->db_encoding);
 665          if (!$collation) {
 666              return '';
 667          }
 668  
 669          return " CHARACTER SET {$this->db_encoding} COLLATE {$collation}";
 670      }
 671  
 672  	public function escape_binary($string)
 673      {
 674          return "X'{$this->escape_string(bin2hex($string))}'";
 675      }
 676  
 677  	public function unescape_binary($string)
 678      {
 679          return $string;
 680      }
 681  
 682      /**
 683       * @param int|string $value
 684       * @param string $quote
 685       *
 686       * @return int|string
 687       */
 688  	private function quote_val($value, $quote="'")
 689      {
 690          if (is_int($value)) {
 691              return $value;
 692          }
 693  
 694          return "{$quote}{$value}{$quote}";
 695      }
 696  
 697  	public function __set($name, $value)
 698      {
 699          if ($name === 'type') {
 700              // NOTE: This is to prevent the type being set - this type should appear as `mysqli` to ensure compatibility
 701              return;
 702          }
 703      }
 704  
 705  	public function __get($name)
 706      {
 707          if ($name === 'type') {
 708              // NOTE: this is to ensure compatibility checks on the DB type will work
 709              return 'mysqli';
 710          }
 711  
 712          return null;
 713      }
 714  }


2005 - 2021 © MyBB.de | Alle Rechte vorbehalten! | Sponsor: netcup Cross-referenced by PHPXref