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

DebugClassLoader.php

Zuletzt modifiziert: 09.10.2024, 12:54 - Dateigröße: 13.00 KiB


 001  <?php
 002   
 003  /*
 004   * This file is part of the Symfony package.
 005   *
 006   * (c) Fabien Potencier <fabien@symfony.com>
 007   *
 008   * For the full copyright and license information, please view the LICENSE
 009   * file that was distributed with this source code.
 010   */
 011   
 012  namespace Symfony\Component\Debug;
 013   
 014  /**
 015   * Autoloader checking if the class is really defined in the file found.
 016   *
 017   * The ClassLoader will wrap all registered autoloaders
 018   * and will throw an exception if a file is found but does
 019   * not declare the class.
 020   *
 021   * @author Fabien Potencier <fabien@symfony.com>
 022   * @author Christophe Coevoet <stof@notk.org>
 023   * @author Nicolas Grekas <p@tchwork.com>
 024   */
 025  class DebugClassLoader
 026  {
 027      private $classLoader;
 028      private $isFinder;
 029      private $wasFinder;
 030      private static $caseCheck;
 031      private static $deprecated = array();
 032      private static $php7Reserved = array('int', 'float', 'bool', 'string', 'true', 'false', 'null');
 033      private static $darwinCache = array('/' => array('/', array()));
 034   
 035      /**
 036       * Constructor.
 037       *
 038       * @param callable|object $classLoader Passing an object is @deprecated since version 2.5 and support for it will be removed in 3.0
 039       */
 040      public function __construct($classLoader)
 041      {
 042          $this->wasFinder = is_object($classLoader) && method_exists($classLoader, 'findFile');
 043   
 044          if ($this->wasFinder) {
 045              @trigger_error('The '.__METHOD__.' method will no longer support receiving an object into its $classLoader argument in 3.0.', E_USER_DEPRECATED);
 046              $this->classLoader = array($classLoader, 'loadClass');
 047              $this->isFinder = true;
 048          } else {
 049              $this->classLoader = $classLoader;
 050              $this->isFinder = is_array($classLoader) && method_exists($classLoader[0], 'findFile');
 051          }
 052   
 053          if (!isset(self::$caseCheck)) {
 054              $file = file_exists(__FILE__) ? __FILE__ : rtrim(realpath('.'), DIRECTORY_SEPARATOR);
 055              $i = strrpos($file, DIRECTORY_SEPARATOR);
 056              $dir = substr($file, 0, 1 + $i);
 057              $file = substr($file, 1 + $i);
 058              $test = strtoupper($file) === $file ? strtolower($file) : strtoupper($file);
 059              $test = realpath($dir.$test);
 060   
 061              if (false === $test || false === $i) {
 062                  // filesystem is case sensitive
 063                  self::$caseCheck = 0;
 064              } elseif (substr($test, -strlen($file)) === $file) {
 065                  // filesystem is case insensitive and realpath() normalizes the case of characters
 066                  self::$caseCheck = 1;
 067              } elseif (false !== stripos(PHP_OS, 'darwin')) {
 068                  // on MacOSX, HFS+ is case insensitive but realpath() doesn't normalize the case of characters
 069                  self::$caseCheck = 2;
 070              } else {
 071                  // filesystem case checks failed, fallback to disabling them
 072                  self::$caseCheck = 0;
 073              }
 074          }
 075      }
 076   
 077      /**
 078       * Gets the wrapped class loader.
 079       *
 080       * @return callable|object A class loader. Since version 2.5, returning an object is @deprecated and support for it will be removed in 3.0
 081       */
 082      public function getClassLoader()
 083      {
 084          return $this->wasFinder ? $this->classLoader[0] : $this->classLoader;
 085      }
 086   
 087      /**
 088       * Wraps all autoloaders.
 089       */
 090      public static function enable()
 091      {
 092          // Ensures we don't hit https://bugs.php.net/42098
 093          class_exists('Symfony\Component\Debug\ErrorHandler');
 094          class_exists('Psr\Log\LogLevel');
 095   
 096          if (!is_array($functions = spl_autoload_functions())) {
 097              return;
 098          }
 099   
 100          foreach ($functions as $function) {
 101              spl_autoload_unregister($function);
 102          }
 103   
 104          foreach ($functions as $function) {
 105              if (!is_array($function) || !$function[0] instanceof self) {
 106                  $function = array(new static($function), 'loadClass');
 107              }
 108   
 109              spl_autoload_register($function);
 110          }
 111      }
 112   
 113      /**
 114       * Disables the wrapping.
 115       */
 116      public static function disable()
 117      {
 118          if (!is_array($functions = spl_autoload_functions())) {
 119              return;
 120          }
 121   
 122          foreach ($functions as $function) {
 123              spl_autoload_unregister($function);
 124          }
 125   
 126          foreach ($functions as $function) {
 127              if (is_array($function) && $function[0] instanceof self) {
 128                  $function = $function[0]->getClassLoader();
 129              }
 130   
 131              spl_autoload_register($function);
 132          }
 133      }
 134   
 135      /**
 136       * Finds a file by class name.
 137       *
 138       * @param string $class A class name to resolve to file
 139       *
 140       * @return string|null
 141       *
 142       * @deprecated since version 2.5, to be removed in 3.0.
 143       */
 144      public function findFile($class)
 145      {
 146          @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED);
 147   
 148          if ($this->wasFinder) {
 149              return $this->classLoader[0]->findFile($class);
 150          }
 151      }
 152   
 153      /**
 154       * Loads the given class or interface.
 155       *
 156       * @param string $class The name of the class
 157       *
 158       * @return bool|null True, if loaded
 159       *
 160       * @throws \RuntimeException
 161       */
 162      public function loadClass($class)
 163      {
 164          ErrorHandler::stackErrors();
 165   
 166          try {
 167              if ($this->isFinder) {
 168                  if ($file = $this->classLoader[0]->findFile($class)) {
 169                      require_once $file;
 170                  }
 171              } else {
 172                  call_user_func($this->classLoader, $class);
 173                  $file = false;
 174              }
 175          } catch (\Exception $e) {
 176              ErrorHandler::unstackErrors();
 177   
 178              throw $e;
 179          } catch (\Throwable $e) {
 180              ErrorHandler::unstackErrors();
 181   
 182              throw $e;
 183          }
 184   
 185          ErrorHandler::unstackErrors();
 186   
 187          $exists = class_exists($class, false) || interface_exists($class, false) || (function_exists('trait_exists') && trait_exists($class, false));
 188   
 189          if ('\\' === $class[0]) {
 190              $class = substr($class, 1);
 191          }
 192   
 193          if ($exists) {
 194              $refl = new \ReflectionClass($class);
 195              $name = $refl->getName();
 196   
 197              if ($name !== $class && 0 === strcasecmp($name, $class)) {
 198                  throw new \RuntimeException(sprintf('Case mismatch between loaded and declared class names: %s vs %s', $class, $name));
 199              }
 200   
 201              if (in_array(strtolower($refl->getShortName()), self::$php7Reserved)) {
 202                  @trigger_error(sprintf('%s uses a reserved class name (%s) that will break on PHP 7 and higher', $name, $refl->getShortName()), E_USER_DEPRECATED);
 203              } elseif (preg_match('#\n \* @deprecated (.*?)\r?\n \*(?: @|/$)#s', $refl->getDocComment(), $notice)) {
 204                  self::$deprecated[$name] = preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]);
 205              } else {
 206                  if (2 > $len = 1 + (strpos($name, '\\', 1 + strpos($name, '\\')) ?: strpos($name, '_'))) {
 207                      $len = 0;
 208                      $ns = '';
 209                  } else {
 210                      switch ($ns = substr($name, 0, $len)) {
 211                          case 'Symfony\Bridge\\':
 212                          case 'Symfony\Bundle\\':
 213                          case 'Symfony\Component\\':
 214                              $ns = 'Symfony\\';
 215                              $len = strlen($ns);
 216                              break;
 217                      }
 218                  }
 219                  $parent = get_parent_class($class);
 220   
 221                  if (!$parent || strncmp($ns, $parent, $len)) {
 222                      if ($parent && isset(self::$deprecated[$parent]) && strncmp($ns, $parent, $len)) {
 223                          @trigger_error(sprintf('The %s class extends %s that is deprecated %s', $name, $parent, self::$deprecated[$parent]), E_USER_DEPRECATED);
 224                      }
 225   
 226                      $parentInterfaces = array();
 227                      $deprecatedInterfaces = array();
 228                      if ($parent) {
 229                          foreach (class_implements($parent) as $interface) {
 230                              $parentInterfaces[$interface] = 1;
 231                          }
 232                      }
 233   
 234                      foreach ($refl->getInterfaceNames() as $interface) {
 235                          if (isset(self::$deprecated[$interface]) && strncmp($ns, $interface, $len)) {
 236                              $deprecatedInterfaces[] = $interface;
 237                          }
 238                          foreach (class_implements($interface) as $interface) {
 239                              $parentInterfaces[$interface] = 1;
 240                          }
 241                      }
 242   
 243                      foreach ($deprecatedInterfaces as $interface) {
 244                          if (!isset($parentInterfaces[$interface])) {
 245                              @trigger_error(sprintf('The %s %s %s that is deprecated %s', $name, $refl->isInterface() ? 'interface extends' : 'class implements', $interface, self::$deprecated[$interface]), E_USER_DEPRECATED);
 246                          }
 247                      }
 248                  }
 249              }
 250          }
 251   
 252          if ($file) {
 253              if (!$exists) {
 254                  if (false !== strpos($class, '/')) {
 255                      throw new \RuntimeException(sprintf('Trying to autoload a class with an invalid name "%s". Be careful that the namespace separator is "\" in PHP, not "/".', $class));
 256                  }
 257   
 258                  throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file));
 259              }
 260              if (self::$caseCheck) {
 261                  $real = explode('\\', $class.strrchr($file, '.'));
 262                  $tail = explode(DIRECTORY_SEPARATOR, str_replace('/', DIRECTORY_SEPARATOR, $file));
 263   
 264                  $i = count($tail) - 1;
 265                  $j = count($real) - 1;
 266   
 267                  while (isset($tail[$i], $real[$j]) && $tail[$i] === $real[$j]) {
 268                      --$i;
 269                      --$j;
 270                  }
 271   
 272                  array_splice($tail, 0, $i + 1);
 273              }
 274              if (self::$caseCheck && $tail) {
 275                  $tail = DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $tail);
 276                  $tailLen = strlen($tail);
 277                  $real = $refl->getFileName();
 278   
 279                  if (2 === self::$caseCheck) {
 280                      // realpath() on MacOSX doesn't normalize the case of characters
 281   
 282                      $i = 1 + strrpos($real, '/');
 283                      $file = substr($real, $i);
 284                      $real = substr($real, 0, $i);
 285   
 286                      if (isset(self::$darwinCache[$real])) {
 287                          $kDir = $real;
 288                      } else {
 289                          $kDir = strtolower($real);
 290   
 291                          if (isset(self::$darwinCache[$kDir])) {
 292                              $real = self::$darwinCache[$kDir][0];
 293                          } else {
 294                              $dir = getcwd();
 295                              chdir($real);
 296                              $real = getcwd().'/';
 297                              chdir($dir);
 298   
 299                              $dir = $real;
 300                              $k = $kDir;
 301                              $i = strlen($dir) - 1;
 302                              while (!isset(self::$darwinCache[$k])) {
 303                                  self::$darwinCache[$k] = array($dir, array());
 304                                  self::$darwinCache[$dir] = &self::$darwinCache[$k];
 305   
 306                                  while ('/' !== $dir[--$i]) {
 307                                  }
 308                                  $k = substr($k, 0, ++$i);
 309                                  $dir = substr($dir, 0, $i--);
 310                              }
 311                          }
 312                      }
 313   
 314                      $dirFiles = self::$darwinCache[$kDir][1];
 315   
 316                      if (isset($dirFiles[$file])) {
 317                          $kFile = $file;
 318                      } else {
 319                          $kFile = strtolower($file);
 320   
 321                          if (!isset($dirFiles[$kFile])) {
 322                              foreach (scandir($real, 2) as $f) {
 323                                  if ('.' !== $f[0]) {
 324                                      $dirFiles[$f] = $f;
 325                                      if ($f === $file) {
 326                                          $kFile = $k = $file;
 327                                      } elseif ($f !== $k = strtolower($f)) {
 328                                          $dirFiles[$k] = $f;
 329                                      }
 330                                  }
 331                              }
 332                              self::$darwinCache[$kDir][1] = $dirFiles;
 333                          }
 334                      }
 335   
 336                      $real .= $dirFiles[$kFile];
 337                  }
 338   
 339                  if (0 === substr_compare($real, $tail, -$tailLen, $tailLen, true)
 340                    && 0 !== substr_compare($real, $tail, -$tailLen, $tailLen, false)
 341                  ) {
 342                      throw new \RuntimeException(sprintf('Case mismatch between class and real file names: %s vs %s in %s', substr($tail, -$tailLen + 1), substr($real, -$tailLen + 1), substr($real, 0, -$tailLen + 1)));
 343                  }
 344              }
 345   
 346              return true;
 347          }
 348      }
 349  }
 350