From e9fbb58f220cd7a187804cdef1cf167f720b42ac Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Tue, 13 Oct 2020 09:58:22 +0200 Subject: [PATCH] Avoid double preloading --- src/Classmap/ClassmapEntryFactory.php | 16 +--------------- src/Classmap/ClassmapFinder.php | 18 +++++++++++++++--- src/PSR4/PSR4Namespace.php | 8 ++++---- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/Classmap/ClassmapEntryFactory.php b/src/Classmap/ClassmapEntryFactory.php index 8be848d..4b423e7 100644 --- a/src/Classmap/ClassmapEntryFactory.php +++ b/src/Classmap/ClassmapEntryFactory.php @@ -18,26 +18,12 @@ class ClassmapEntryFactory /** * @return ClassmapEntry[] */ - public function getClassmapEntries($allowAdditional) + public function getClassmapEntries() { // Composer will compile user declared mappings to autoload_classmap.php. So no additional work is needed // to fetch user provided entries. $classmap = require($this->appConfig->getAppRoot().'vendor/composer/autoload_classmap.php'); - $finalClassMap = []; - foreach ($classmap as $potentialClass => $file) { - if (\function_exists($potentialClass)) { - if ($allowAdditional & ClassFinder::ALLOW_FUNCTIONS) { - $finalClassMap[$potentialClass] = $file; - } - } elseif ($allowAdditional & ClassFinder::ALLOW_CLASSES && \class_exists($potentialClass) - || ($allowAdditional & ClassFinder::ALLOW_INTERFACES && \interface_exists($potentialClass)) - || ($allowAdditional & ClassFinder::ALLOW_TRAITS && \trait_exists($potentialClass))) { - $finalClassMap[$potentialClass] = $file; - } - } - $classmap = $finalClassMap; - // if classmap has no entries return empty array if (\count($classmap) == 0) { return []; diff --git a/src/Classmap/ClassmapFinder.php b/src/Classmap/ClassmapFinder.php index 3fc592a..93caa9f 100644 --- a/src/Classmap/ClassmapFinder.php +++ b/src/Classmap/ClassmapFinder.php @@ -21,7 +21,7 @@ class ClassmapFinder implements FinderInterface */ public function isNamespaceKnown($namespace) { - $classmapEntries = $this->factory->getClassmapEntries(ClassFinder::ALLOW_ALL); + $classmapEntries = $this->factory->getClassmapEntries(); foreach($classmapEntries as $classmapEntry) { if ($classmapEntry->knowsNamespace($namespace)) { @@ -39,10 +39,22 @@ class ClassmapFinder implements FinderInterface */ public function findClasses($namespace, $options) { - $classmapEntries = $this->factory->getClassmapEntries($options); + $classmapEntries = $this->factory->getClassmapEntries(); $matchingEntries = array_filter($classmapEntries, function(ClassmapEntry $entry) use ($namespace, $options) { - return $entry->matches($namespace, $options); + if (!$entry->matches($namespace, $options)) return false; + $potentialClass = $entry->getClassName(); + if (function_exists($potentialClass)) { + // For some reason calling class_exists() on a namespace'd function raises a Fatal Error (tested PHP 7.0.8) + // Example: DeepCopy\deep_copy + return $options & ClassFinder::ALLOW_FUNCTIONS; + } else if (class_exists($potentialClass)) { + return $options & ClassFinder::ALLOW_CLASSES; + } else if (interface_exists($potentialClass, false)) { + return $options & ClassFinder::ALLOW_INTERFACES; + } else if (trait_exists($potentialClass, false)) { + return $options & ClassFinder::ALLOW_TRAITS; + } }); return array_map(function(ClassmapEntry $entry) { diff --git a/src/PSR4/PSR4Namespace.php b/src/PSR4/PSR4Namespace.php index 6f81996..5563d18 100644 --- a/src/PSR4/PSR4Namespace.php +++ b/src/PSR4/PSR4Namespace.php @@ -206,8 +206,8 @@ class PSR4Namespace return ($allowAdditional & ClassFinder::ALLOW_FUNCTIONS); } else { return ($allowAdditional & ClassFinder::ALLOW_CLASSES && class_exists($potentialClass)) - || ($allowAdditional & ClassFinder::ALLOW_INTERFACES && interface_exists($potentialClass)) - || ($allowAdditional & ClassFinder::ALLOW_TRAITS && trait_exists($potentialClass)); + || ($allowAdditional & ClassFinder::ALLOW_INTERFACES && interface_exists($potentialClass, false)) + || ($allowAdditional & ClassFinder::ALLOW_TRAITS && trait_exists($potentialClass, false)); } }); } @@ -250,8 +250,8 @@ class PSR4Namespace return ($allowAdditional & ClassFinder::ALLOW_FUNCTIONS); } else { return ($allowAdditional & ClassFinder::ALLOW_CLASSES && class_exists($potentialClass)) - || ($allowAdditional & ClassFinder::ALLOW_INTERFACES && interface_exists($potentialClass)) - || ($allowAdditional & ClassFinder::ALLOW_TRAITS && trait_exists($potentialClass)); + || ($allowAdditional & ClassFinder::ALLOW_INTERFACES && interface_exists($potentialClass, false)) + || ($allowAdditional & ClassFinder::ALLOW_TRAITS && trait_exists($potentialClass, false)); } }); }