Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

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

ClassExistenceResource.php

Zuletzt modifiziert: 02.04.2025, 15:03 - Dateigröße: 7.11 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\Config\Resource;
013   
014  /**
015   * ClassExistenceResource represents a class existence.
016   * Freshness is only evaluated against resource existence.
017   *
018   * The resource must be a fully-qualified class name.
019   *
020   * @author Fabien Potencier <fabien@symfony.com>
021   */
022  class ClassExistenceResource implements SelfCheckingResourceInterface, \Serializable
023  {
024      private $resource;
025      private $exists;
026   
027      private static $autoloadLevel = 0;
028      private static $autoloadedClass;
029      private static $existsCache = [];
030   
031      /**
032       * @param string    $resource The fully-qualified class name
033       * @param bool|null $exists   Boolean when the existency check has already been done
034       */
035      public function __construct($resource, $exists = null)
036      {
037          $this->resource = $resource;
038          if (null !== $exists) {
039              $this->exists = [(bool) $exists, null];
040          }
041      }
042   
043      /**
044       * {@inheritdoc}
045       */
046      public function __toString()
047      {
048          return $this->resource;
049      }
050   
051      /**
052       * @return string The file path to the resource
053       */
054      public function getResource()
055      {
056          return $this->resource;
057      }
058   
059      /**
060       * {@inheritdoc}
061       *
062       * @throws \ReflectionException when a parent class/interface/trait is not found
063       */
064      public function isFresh($timestamp)
065      {
066          $loaded = class_exists($this->resource, false) || interface_exists($this->resource, false) || trait_exists($this->resource, false);
067   
068          if (null !== $exists = &self::$existsCache[$this->resource]) {
069              if ($loaded) {
070                  $exists = [true, null];
071              } elseif (0 >= $timestamp && !$exists[0] && null !== $exists[1]) {
072                  throw new \ReflectionException($exists[1]);
073              }
074          } elseif ([false, null] === $exists = [$loaded, null]) {
075              if (!self::$autoloadLevel++) {
076                  spl_autoload_register(__CLASS__.'::throwOnRequiredClass');
077              }
078              $autoloadedClass = self::$autoloadedClass;
079              self::$autoloadedClass = ltrim($this->resource, '\\');
080   
081              try {
082                  $exists[0] = class_exists($this->resource) || interface_exists($this->resource, false) || trait_exists($this->resource, false);
083              } catch (\Exception $e) {
084                  $exists[1] = $e->getMessage();
085   
086                  try {
087                      self::throwOnRequiredClass($this->resource, $e);
088                  } catch (\ReflectionException $e) {
089                      if (0 >= $timestamp) {
090                          throw $e;
091                      }
092                  }
093              } catch (\Throwable $e) {
094                  $exists[1] = $e->getMessage();
095   
096                  throw $e;
097              } finally {
098                  self::$autoloadedClass = $autoloadedClass;
099                  if (!--self::$autoloadLevel) {
100                      spl_autoload_unregister(__CLASS__.'::throwOnRequiredClass');
101                  }
102              }
103          }
104   
105          if (null === $this->exists) {
106              $this->exists = $exists;
107          }
108   
109          return $this->exists[0] xor !$exists[0];
110      }
111   
112      /**
113       * @internal
114       */
115      public function serialize()
116      {
117          if (null === $this->exists) {
118              $this->isFresh(0);
119          }
120   
121          return serialize([$this->resource, $this->exists]);
122      }
123   
124      /**
125       * @internal
126       */
127      public function unserialize($serialized)
128      {
129          list($this->resource, $this->exists) = unserialize($serialized);
130   
131          if (\is_bool($this->exists)) {
132              $this->exists = [$this->exists, null];
133          }
134      }
135   
136      /**
137       * Throws a reflection exception when the passed class does not exist but is required.
138       *
139       * A class is considered "not required" when it's loaded as part of a "class_exists" or similar check.
140       *
141       * This function can be used as an autoload function to throw a reflection
142       * exception if the class was not found by previous autoload functions.
143       *
144       * A previous exception can be passed. In this case, the class is considered as being
145       * required totally, so if it doesn't exist, a reflection exception is always thrown.
146       * If it exists, the previous exception is rethrown.
147       *
148       * @throws \ReflectionException
149       *
150       * @internal
151       */
152      public static function throwOnRequiredClass($class, \Exception $previous = null)
153      {
154          // If the passed class is the resource being checked, we shouldn't throw.
155          if (null === $previous && self::$autoloadedClass === $class) {
156              return;
157          }
158   
159          if (class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false)) {
160              if (null !== $previous) {
161                  throw $previous;
162              }
163   
164              return;
165          }
166   
167          if ($previous instanceof \ReflectionException) {
168              throw $previous;
169          }
170   
171          $message = sprintf('Class "%s" not found.', $class);
172   
173          if (self::$autoloadedClass !== $class) {
174              $message = substr_replace($message, sprintf(' while loading "%s"', self::$autoloadedClass), -1, 0);
175          }
176   
177          if (null !== $previous) {
178              $message = $previous->getMessage();
179          }
180   
181          $e = new \ReflectionException($message, 0, $previous);
182   
183          if (null !== $previous) {
184              throw $e;
185          }
186   
187          $trace = debug_backtrace();
188          $autoloadFrame = [
189              'function' => 'spl_autoload_call',
190              'args' => [$class],
191          ];
192   
193          if (\PHP_VERSION_ID >= 80000 && isset($trace[1])) {
194              $callerFrame = $trace[1];
195              $i = 2;
196          } elseif (false !== $i = array_search($autoloadFrame, $trace, true)) {
197              $callerFrame = $trace[++$i];
198          } else {
199              throw $e;
200          }
201   
202          if (isset($callerFrame['function']) && !isset($callerFrame['class'])) {
203              switch ($callerFrame['function']) {
204                  case 'get_class_methods':
205                  case 'get_class_vars':
206                  case 'get_parent_class':
207                  case 'is_a':
208                  case 'is_subclass_of':
209                  case 'class_exists':
210                  case 'class_implements':
211                  case 'class_parents':
212                  case 'trait_exists':
213                  case 'defined':
214                  case 'interface_exists':
215                  case 'method_exists':
216                  case 'property_exists':
217                  case 'is_callable':
218                      return;
219              }
220   
221              $props = [
222                  'file' => isset($callerFrame['file']) ? $callerFrame['file'] : null,
223                  'line' => isset($callerFrame['line']) ? $callerFrame['line'] : null,
224                  'trace' => \array_slice($trace, 1 + $i),
225              ];
226   
227              foreach ($props as $p => $v) {
228                  if (null !== $v) {
229                      $r = new \ReflectionProperty('Exception', $p);
230                      $r->setAccessible(true);
231                      $r->setValue($e, $v);
232                  }
233              }
234          }
235   
236          throw $e;
237      }
238  }
239