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

file.php

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