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