From 6659ed60f160a1fca31e1ad40e7dd8ac88351096 Mon Sep 17 00:00:00 2001 From: Kostya Shkryob Date: Wed, 25 Mar 2020 18:58:21 +0200 Subject: [PATCH 1/2] Cache reference files --- src/spec/Reference.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/spec/Reference.php b/src/spec/Reference.php index 1eef2eca..6ed56c25 100644 --- a/src/spec/Reference.php +++ b/src/spec/Reference.php @@ -29,6 +29,8 @@ */ class Reference implements SpecObjectInterface, DocumentContextInterface { + static $file_cache = []; + private $_to; private $_ref; private $_jsonReference; @@ -263,6 +265,10 @@ public function resolve(ReferenceContext $context = null) */ private function fetchReferencedFile($uri) { + if (isset(self::$file_cache[$uri])) { + return self::$file_cache[$uri]; + } + try { $content = file_get_contents($uri); if ($content === false) { @@ -272,10 +278,11 @@ private function fetchReferencedFile($uri) } // TODO lazy content detection, should probably be improved if (strpos(ltrim($content), '{') === 0) { - return json_decode($content, true); + self::$file_cache[$uri] = json_decode($content, true); } else { - return Yaml::parse($content); + self::$file_cache[$uri] = Yaml::parse($content); } + return self::$file_cache[$uri]; } catch (\Throwable $e) { $exception = new UnresolvableReferenceException( "Failed to resolve Reference '$this->_ref' to $this->_to Object: " . $e->getMessage(), From 4d78a24e1b4dc097ac74b32b9681095387dc53ff Mon Sep 17 00:00:00 2001 From: Kostya Shkryob Date: Thu, 26 Mar 2020 16:01:28 +0200 Subject: [PATCH 2/2] Move cache logic to separate function --- src/spec/Reference.php | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/spec/Reference.php b/src/spec/Reference.php index 6ed56c25..5b5b88c7 100644 --- a/src/spec/Reference.php +++ b/src/spec/Reference.php @@ -208,7 +208,7 @@ public function resolve(ReferenceContext $context = null) // resolve in external document $file = $context->resolveRelativeUri($jsonReference->getDocumentUri()); // TODO could be a good idea to cache loaded files in current context to avoid loading the same files over and over again - $referencedDocument = $this->fetchReferencedFile($file); + $referencedDocument = $this->getReferencedFile($file); $referencedData = $jsonReference->getJsonPointer()->evaluate($referencedDocument); if ($referencedData === null) { @@ -263,12 +263,20 @@ public function resolve(ReferenceContext $context = null) /** * @throws UnresolvableReferenceException */ - private function fetchReferencedFile($uri) + private function getReferencedFile($uri) { - if (isset(self::$file_cache[$uri])) { - return self::$file_cache[$uri]; + if(!isset(self::$file_cache[$uri])) { + self::$file_cache[$uri] = $this->fetchReferencedFile($uri); } + return self::$file_cache[$uri]; + } + + /** + * @throws UnresolvableReferenceException + */ + private function fetchReferencedFile($uri) + { try { $content = file_get_contents($uri); if ($content === false) { @@ -278,11 +286,10 @@ private function fetchReferencedFile($uri) } // TODO lazy content detection, should probably be improved if (strpos(ltrim($content), '{') === 0) { - self::$file_cache[$uri] = json_decode($content, true); + return json_decode($content, true); } else { - self::$file_cache[$uri] = Yaml::parse($content); + return Yaml::parse($content); } - return self::$file_cache[$uri]; } catch (\Throwable $e) { $exception = new UnresolvableReferenceException( "Failed to resolve Reference '$this->_ref' to $this->_to Object: " . $e->getMessage(),