Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

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

file.php

Zuletzt modifiziert: 09.10.2024, 12:54 - Dateigröße: 10.84 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\cache\driver;
 015   
 016  /**
 017  * ACM File Based Caching
 018  */
 019  class file extends \phpbb\cache\driver\base
 020  {
 021      var $var_expires = array();
 022   
 023      /**
 024      * Set cache path
 025      *
 026      * @param string $cache_dir Define the path to the cache directory (default: $phpbb_root_path . 'cache/')
 027      */
 028      function __construct($cache_dir = null)
 029      {
 030          global $phpbb_root_path;
 031          $this->cache_dir = !is_null($cache_dir) ? $cache_dir : $phpbb_root_path . 'cache/';
 032      }
 033   
 034      /**
 035      * {@inheritDoc}
 036      */
 037      function load()
 038      {
 039          return $this->_read('data_global');
 040      }
 041   
 042      /**
 043      * {@inheritDoc}
 044      */
 045      function unload()
 046      {
 047          parent::unload();
 048          unset($this->var_expires);
 049          $this->var_expires = array();
 050      }
 051   
 052      /**
 053      * {@inheritDoc}
 054      */
 055      function save()
 056      {
 057          if (!$this->is_modified)
 058          {
 059              return;
 060          }
 061   
 062          global $phpEx;
 063   
 064          if (!$this->_write('data_global'))
 065          {
 066              if (!function_exists('phpbb_is_writable'))
 067              {
 068                  global $phpbb_root_path;
 069                  include($phpbb_root_path . 'includes/functions.' . $phpEx);
 070              }
 071   
 072              // Now, this occurred how often? ... phew, just tell the user then...
 073              if (!phpbb_is_writable($this->cache_dir))
 074              {
 075                  // We need to use die() here, because else we may encounter an infinite loop (the message handler calls $cache->unload())
 076                  die('Fatal: ' . $this->cache_dir . ' is NOT writable.');
 077                  exit;
 078              }
 079   
 080              die('Fatal: Not able to open ' . $this->cache_dir . 'data_global.' . $phpEx);
 081              exit;
 082          }
 083   
 084          $this->is_modified = false;
 085      }
 086   
 087      /**
 088      * {@inheritDoc}
 089      */
 090      function tidy()
 091      {
 092          global $phpEx;
 093   
 094          $dir = @opendir($this->cache_dir);
 095   
 096          if (!$dir)
 097          {
 098              return;
 099          }
 100   
 101          $time = time();
 102   
 103          while (($entry = readdir($dir)) !== false)
 104          {
 105              if (!preg_match('/^(sql_|data_(?!global))/', $entry))
 106              {
 107                  continue;
 108              }
 109   
 110              if (!($handle = @fopen($this->cache_dir . $entry, 'rb')))
 111              {
 112                  continue;
 113              }
 114   
 115              // Skip the PHP header
 116              fgets($handle);
 117   
 118              // Skip expiration
 119              $expires = (int) fgets($handle);
 120   
 121              fclose($handle);
 122   
 123              if ($time >= $expires)
 124              {
 125                  $this->remove_file($this->cache_dir . $entry);
 126              }
 127          }
 128          closedir($dir);
 129   
 130          if (file_exists($this->cache_dir . 'data_global.' . $phpEx))
 131          {
 132              if (!sizeof($this->vars))
 133              {
 134                  $this->load();
 135              }
 136   
 137              foreach ($this->var_expires as $var_name => $expires)
 138              {
 139                  if ($time >= $expires)
 140                  {
 141                      $this->destroy($var_name);
 142                  }
 143              }
 144          }
 145   
 146          set_config('cache_last_gc', time(), true);
 147      }
 148   
 149      /**
 150      * {@inheritDoc}
 151      */
 152      function get($var_name)
 153      {
 154          if ($var_name[0] == '_')
 155          {
 156              if (!$this->_exists($var_name))
 157              {
 158                  return false;
 159              }
 160   
 161              return $this->_read('data' . $var_name);
 162          }
 163          else
 164          {
 165              return ($this->_exists($var_name)) ? $this->vars[$var_name] : false;
 166          }
 167      }
 168   
 169      /**
 170      * {@inheritDoc}
 171      */
 172      function put($var_name, $var, $ttl = 31536000)
 173      {
 174          if ($var_name[0] == '_')
 175          {
 176              $this->_write('data' . $var_name, $var, time() + $ttl);
 177          }
 178          else
 179          {
 180              $this->vars[$var_name] = $var;
 181              $this->var_expires[$var_name] = time() + $ttl;
 182              $this->is_modified = true;
 183          }
 184      }
 185   
 186      /**
 187      * {@inheritDoc}
 188      */
 189      function purge()
 190      {
 191          parent::purge();
 192          $this->var_expires = array();
 193      }
 194   
 195      /**
 196      * {@inheritDoc}
 197      */
 198      function destroy($var_name, $table = '')
 199      {
 200          global $phpEx;
 201   
 202          if ($var_name == 'sql' && !empty($table))
 203          {
 204              if (!is_array($table))
 205              {
 206                  $table = array($table);
 207              }
 208   
 209              $dir = @opendir($this->cache_dir);
 210   
 211              if (!$dir)
 212              {
 213                  return;
 214              }
 215   
 216              while (($entry = readdir($dir)) !== false)
 217              {
 218                  if (strpos($entry, 'sql_') !== 0)
 219                  {
 220                      continue;
 221                  }
 222   
 223                  if (!($handle = @fopen($this->cache_dir . $entry, 'rb')))
 224                  {
 225                      continue;
 226                  }
 227   
 228                  // Skip the PHP header
 229                  fgets($handle);
 230   
 231                  // Skip expiration
 232                  fgets($handle);
 233   
 234                  // Grab the query, remove the LF
 235                  $query = substr(fgets($handle), 0, -1);
 236   
 237                  fclose($handle);
 238   
 239                  foreach ($table as $check_table)
 240                  {
 241                      // Better catch partial table names than no table names. ;)
 242                      if (strpos($query, $check_table) !== false)
 243                      {
 244                          $this->remove_file($this->cache_dir . $entry);
 245                          break;
 246                      }
 247                  }
 248              }
 249              closedir($dir);
 250   
 251              return;
 252          }
 253   
 254          if (!$this->_exists($var_name))
 255          {
 256              return;
 257          }
 258   
 259          if ($var_name[0] == '_')
 260          {
 261              $this->remove_file($this->cache_dir . 'data' . $var_name . ".$phpEx", true);
 262          }
 263          else if (isset($this->vars[$var_name]))
 264          {
 265              $this->is_modified = true;
 266              unset($this->vars[$var_name]);
 267              unset($this->var_expires[$var_name]);
 268   
 269              // We save here to let the following cache hits succeed
 270              $this->save();
 271          }
 272      }
 273   
 274      /**
 275      * {@inheritDoc}
 276      */
 277      function _exists($var_name)
 278      {
 279          if ($var_name[0] == '_')
 280          {
 281              global $phpEx;
 282              return file_exists($this->cache_dir . 'data' . $var_name . ".$phpEx");
 283          }
 284          else
 285          {
 286              if (!sizeof($this->vars))
 287              {
 288                  $this->load();
 289              }
 290   
 291              if (!isset($this->var_expires[$var_name]))
 292              {
 293                  return false;
 294              }
 295   
 296              return (time() > $this->var_expires[$var_name]) ? false : isset($this->vars[$var_name]);
 297          }
 298      }
 299   
 300      /**
 301      * {@inheritDoc}
 302      */
 303      function sql_save(\phpbb\db\driver\driver_interface $db, $query, $query_result, $ttl)
 304      {
 305          // Remove extra spaces and tabs
 306          $query = preg_replace('/[\n\r\s\t]+/', ' ', $query);
 307   
 308          $query_id = sizeof($this->sql_rowset);
 309          $this->sql_rowset[$query_id] = array();
 310          $this->sql_row_pointer[$query_id] = 0;
 311   
 312          while ($row = $db->sql_fetchrow($query_result))
 313          {
 314              $this->sql_rowset[$query_id][] = $row;
 315          }
 316          $db->sql_freeresult($query_result);
 317   
 318          if ($this->_write('sql_' . md5($query), $this->sql_rowset[$query_id], $ttl + time(), $query))
 319          {
 320              return $query_id;
 321          }
 322   
 323          return $query_result;
 324      }
 325   
 326      /**
 327      * Read cached data from a specified file
 328      *
 329      * @access private
 330      * @param string $filename Filename to write
 331      * @return mixed False if an error was encountered, otherwise the data type of the cached data
 332      */
 333      function _read($filename)
 334      {
 335          global $phpEx;
 336   
 337          $file = "{$this->cache_dir}$filename.$phpEx";
 338   
 339          $type = substr($filename, 0, strpos($filename, '_'));
 340   
 341          if (!file_exists($file))
 342          {
 343              return false;
 344          }
 345   
 346          if (!($handle = @fopen($file, 'rb')))
 347          {
 348              return false;
 349          }
 350   
 351          // Skip the PHP header
 352          fgets($handle);
 353   
 354          if ($filename == 'data_global')
 355          {
 356              $this->vars = $this->var_expires = array();
 357   
 358              $time = time();
 359   
 360              while (($expires = (int) fgets($handle)) && !feof($handle))
 361              {
 362                  // Number of bytes of data
 363                  $bytes = substr(fgets($handle), 0, -1);
 364   
 365                  if (!is_numeric($bytes) || ($bytes = (int) $bytes) === 0)
 366                  {
 367                      // We cannot process the file without a valid number of bytes
 368                      // so we discard it
 369                      fclose($handle);
 370   
 371                      $this->vars = $this->var_expires = array();
 372                      $this->is_modified = false;
 373   
 374                      $this->remove_file($file);
 375   
 376                      return false;
 377                  }
 378   
 379                  if ($time >= $expires)
 380                  {
 381                      fseek($handle, $bytes, SEEK_CUR);
 382   
 383                      continue;
 384                  }
 385   
 386                  $var_name = substr(fgets($handle), 0, -1);
 387   
 388                  // Read the length of bytes that consists of data.
 389                  $data = fread($handle, $bytes - strlen($var_name));
 390                  $data = @unserialize($data);
 391   
 392                  // Don't use the data if it was invalid
 393                  if ($data !== false)
 394                  {
 395                      $this->vars[$var_name] = $data;
 396                      $this->var_expires[$var_name] = $expires;
 397                  }
 398   
 399                  // Absorb the LF
 400                  fgets($handle);
 401              }
 402   
 403              fclose($handle);
 404   
 405              $this->is_modified = false;
 406   
 407              return true;
 408          }
 409          else
 410          {
 411              $data = false;
 412              $line = 0;
 413   
 414              while (($buffer = fgets($handle)) && !feof($handle))
 415              {
 416                  $buffer = substr($buffer, 0, -1); // Remove the LF
 417   
 418                  // $buffer is only used to read integers
 419                  // if it is non numeric we have an invalid
 420                  // cache file, which we will now remove.
 421                  if (!is_numeric($buffer))
 422                  {
 423                      break;
 424                  }
 425   
 426                  if ($line == 0)
 427                  {
 428                      $expires = (int) $buffer;
 429   
 430                      if (time() >= $expires)
 431                      {
 432                          break;
 433                      }
 434   
 435                      if ($type == 'sql')
 436                      {
 437                          // Skip the query
 438                          fgets($handle);
 439                      }
 440                  }
 441                  else if ($line == 1)
 442                  {
 443                      $bytes = (int) $buffer;
 444   
 445                      // Never should have 0 bytes
 446                      if (!$bytes)
 447                      {
 448                          break;
 449                      }
 450   
 451                      // Grab the serialized data
 452                      $data = fread($handle, $bytes);
 453   
 454                      // Read 1 byte, to trigger EOF
 455                      fread($handle, 1);
 456   
 457                      if (!feof($handle))
 458                      {
 459                          // Somebody tampered with our data
 460                          $data = false;
 461                      }
 462                      break;
 463                  }
 464                  else
 465                  {
 466                      // Something went wrong
 467                      break;
 468                  }
 469                  $line++;
 470              }
 471              fclose($handle);
 472   
 473              // unserialize if we got some data
 474              $data = ($data !== false) ? @unserialize($data) : $data;
 475   
 476              if ($data === false)
 477              {
 478                  $this->remove_file($file);
 479                  return false;
 480              }
 481   
 482              return $data;
 483          }
 484      }
 485   
 486      /**
 487      * Write cache data to a specified file
 488      *
 489      * 'data_global' is a special case and the generated format is different for this file:
 490      * <code>
 491      * <?php exit; ?>
 492      * (expiration)
 493      * (length of var and serialised data)
 494      * (var)
 495      * (serialised data)
 496      * ... (repeat)
 497      * </code>
 498      *
 499      * The other files have a similar format:
 500      * <code>
 501      * <?php exit; ?>
 502      * (expiration)
 503      * (query) [SQL files only]
 504      * (length of serialised data)
 505      * (serialised data)
 506      * </code>
 507      *
 508      * @access private
 509      * @param string $filename Filename to write
 510      * @param mixed $data Data to store
 511      * @param int $expires Timestamp when the data expires
 512      * @param string $query Query when caching SQL queries
 513      * @return bool True if the file was successfully created, otherwise false
 514      */
 515      function _write($filename, $data = null, $expires = 0, $query = '')
 516      {
 517          global $phpEx;
 518   
 519          $file = "{$this->cache_dir}$filename.$phpEx";
 520   
 521          $lock = new \phpbb\lock\flock($file);
 522          $lock->acquire();
 523   
 524          if ($handle = @fopen($file, 'wb'))
 525          {
 526              // File header
 527              fwrite($handle, '<' . '?php exit; ?' . '>');
 528   
 529              if ($filename == 'data_global')
 530              {
 531                  // Global data is a different format
 532                  foreach ($this->vars as $var => $data)
 533                  {
 534                      if (strpos($var, "\r") !== false || strpos($var, "\n") !== false)
 535                      {
 536                          // CR/LF would cause fgets() to read the cache file incorrectly
 537                          // do not cache test entries, they probably won't be read back
 538                          // the cache keys should really be alphanumeric with a few symbols.
 539                          continue;
 540                      }
 541                      $data = serialize($data);
 542   
 543                      // Write out the expiration time
 544                      fwrite($handle, "\n" . $this->var_expires[$var] . "\n");
 545   
 546                      // Length of the remaining data for this var (ignoring two LF's)
 547                      fwrite($handle, strlen($data . $var) . "\n");
 548                      fwrite($handle, $var . "\n");
 549                      fwrite($handle, $data);
 550                  }
 551              }
 552              else
 553              {
 554                  fwrite($handle, "\n" . $expires . "\n");
 555   
 556                  if (strpos($filename, 'sql_') === 0)
 557                  {
 558                      fwrite($handle, $query . "\n");
 559                  }
 560                  $data = serialize($data);
 561   
 562                  fwrite($handle, strlen($data) . "\n");
 563                  fwrite($handle, $data);
 564              }
 565   
 566              fclose($handle);
 567   
 568              if (!function_exists('phpbb_chmod'))
 569              {
 570                  global $phpbb_root_path;
 571                  include($phpbb_root_path . 'includes/functions.' . $phpEx);
 572              }
 573   
 574              phpbb_chmod($file, CHMOD_READ | CHMOD_WRITE);
 575   
 576              $return_value = true;
 577          }
 578          else
 579          {
 580              $return_value = false;
 581          }
 582   
 583          $lock->release();
 584   
 585          return $return_value;
 586      }
 587  }
 588