상속: extends StringFrontend
 /**
  * Flushes the cache either by entry or flushes
  * the entire cache if no entry is provided.
  *
  * @param string|null $name
  * @return bool|void
  */
 public function flush($name = null)
 {
     if ($name !== null) {
         return $this->flowCache->remove($name);
     } else {
         return $this->flowCache->flush();
     }
 }
 /**
  * Shutdown the Evaluator
  */
 public function shutdownObject()
 {
     if (count($this->newExpressions) > 0) {
         $changesToPersist = false;
         $codeToBeCached = $this->expressionCache->get('cachedExpressionClosures');
         /**
          * At this point a race condition could happen, that we try to prevent with an additional check.
          * So we compare the evaluated expressions during this request with the methods the cache has at
          * this point and only add methods that are not present. Only if we added anything we write the cache.
          */
         foreach ($this->newExpressions as $functionName => $newExpression) {
             if (strpos($codeToBeCached, $functionName) === false) {
                 $codeToBeCached .= 'if (!function_exists(\'' . $functionName . '\')) { ' . $newExpression . ' }' . chr(10);
                 $changesToPersist = true;
             }
         }
         if ($changesToPersist) {
             $this->expressionCache->set('cachedExpressionClosures', $codeToBeCached);
         }
     }
 }
예제 #3
0
 /**
  * Reads the specified class file, appends ORIGINAL_CLASSNAME_SUFFIX to its
  * class name and stores the result in the proxy classes cache.
  *
  * @param string $className Short class name of the class to copy
  * @param string $pathAndFilename Full path and filename of the original class file
  * @param string $proxyClassCode The code that makes up the proxy class
  * @return void
  *
  * @throws Exception If the original class filename doesn't match the actual class name inside the file.
  */
 protected function cacheOriginalClassFileAndProxyCode($className, $pathAndFilename, $proxyClassCode)
 {
     $classCode = file_get_contents($pathAndFilename);
     $classCode = $this->stripOpeningPhpTag($classCode);
     $classNameSuffix = self::ORIGINAL_CLASSNAME_SUFFIX;
     $classCode = preg_replace_callback('/^([a-z\\s]*?)(final\\s+)?(interface|class)\\s+([a-zA-Z0-9_]+)/m', function ($matches) use($pathAndFilename, $classNameSuffix, $proxyClassCode) {
         $classNameAccordingToFileName = basename($pathAndFilename, '.php');
         if ($matches[4] !== $classNameAccordingToFileName) {
             throw new Exception('The name of the class "' . $matches[4] . '" is not the same as the filename which is "' . basename($pathAndFilename) . '". Path: ' . $pathAndFilename, 1398356897);
         }
         return $matches[1] . $matches[3] . ' ' . $matches[4] . $classNameSuffix;
     }, $classCode);
     $classCode = preg_replace('/\\?>[\\n\\s\\r]*$/', '', $classCode);
     $proxyClassCode .= "\n" . '# PathAndFilename: ' . $pathAndFilename;
     $this->classesCache->set(str_replace('\\', '_', $className), $classCode . $proxyClassCode);
 }
 /**
  * Loads php files containing classes or interfaces found in the classes directory of
  * a package and specifically registered classes.
  *
  * @param string $className Name of the class/interface to load
  * @return boolean
  */
 public function loadClass($className)
 {
     if ($className[0] === '\\') {
         $className = ltrim($className, '\\');
     }
     $namespaceParts = explode('\\', $className);
     // Workaround for Doctrine's annotation parser which does a class_exists() for annotations like "@param" and so on:
     if (isset($this->ignoredClassNames[$className]) || isset($this->ignoredClassNames[end($namespaceParts)]) || isset($this->nonExistentClasses[$className])) {
         return false;
     }
     // Loads any known proxied class:
     if ($this->classesCache !== null && ($this->availableProxyClasses === null || isset($this->availableProxyClasses[implode('_', $namespaceParts)])) && $this->classesCache->requireOnce(implode('_', $namespaceParts)) !== false) {
         return true;
     }
     $classNamePart = array_pop($namespaceParts);
     $classNameParts = explode('_', $classNamePart);
     $namespaceParts = array_merge($namespaceParts, $classNameParts);
     $namespacePartCount = count($namespaceParts);
     $currentPackageArray = $this->packageNamespaces;
     $packagenamespacePartCount = 0;
     // This will contain all possible class mappings for the given class name. We start with the fallback paths and prepend mappings with growing specificy.
     $collectedPossibleNamespaceMappings = [['p' => $this->fallbackClassPaths, 'c' => 0]];
     if ($namespacePartCount > 1) {
         while ($packagenamespacePartCount + 1 < $namespacePartCount) {
             $possiblePackageNamespacePart = $namespaceParts[$packagenamespacePartCount];
             if (!isset($currentPackageArray[$possiblePackageNamespacePart])) {
                 break;
             }
             $packagenamespacePartCount++;
             $currentPackageArray = $currentPackageArray[$possiblePackageNamespacePart];
             if (isset($currentPackageArray['_pathData'])) {
                 array_unshift($collectedPossibleNamespaceMappings, ['p' => $currentPackageArray['_pathData'], 'c' => $packagenamespacePartCount]);
             }
         }
     }
     foreach ($collectedPossibleNamespaceMappings as $nameSpaceMapping) {
         if ($this->loadClassFromPossiblePaths($nameSpaceMapping['p'], $namespaceParts, $nameSpaceMapping['c'])) {
             return true;
         }
     }
     $this->nonExistentClasses[$className] = true;
     return false;
 }
 /**
  * Flush all runtime expressions
  *
  * @return void
  */
 public function flush()
 {
     $this->runtimeExpressionsCache->flush();
 }