mirror of
https://github.com/twigphp/Twig.git
synced 2026-10-02 18:07:35 +00:00
Reuse the template wrapper of an already loaded template
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
# 3.30.0 (2026-XX-XX)
|
||||
|
||||
* Fix the escaping safe analysis retaining every compiled template node for the lifetime of the environment
|
||||
* Speed up loading a template that the environment has already loaded
|
||||
* Fix `IntlExtension` letting the pattern derived from a date formatter prototype override an explicit locale
|
||||
* Fix `IntlExtension` not honoring the locale of a date formatter prototype configured with no date and time styles
|
||||
* Speed up macro calls
|
||||
|
||||
+8
-1
@@ -72,6 +72,10 @@ class Environment
|
||||
private $useYield;
|
||||
private $defaultRuntimeLoader;
|
||||
private array $hotCache = [];
|
||||
/**
|
||||
* @var array<string, TemplateWrapper>
|
||||
*/
|
||||
private array $loadedWrappers = [];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -255,6 +259,7 @@ class Environment
|
||||
{
|
||||
$cls = $this->getTemplateClass($name);
|
||||
$this->hotCache[$name] = $cls.'_'.bin2hex(random_bytes(16));
|
||||
unset($this->loadedWrappers[$cls]);
|
||||
|
||||
if ($this->cache instanceof RemovableCacheInterface) {
|
||||
$this->cache->remove($name, $cls);
|
||||
@@ -374,7 +379,9 @@ class Environment
|
||||
return $name;
|
||||
}
|
||||
|
||||
return new TemplateWrapper($this, $this->loadTemplate($this->getTemplateClass($name), $name));
|
||||
$cls = $this->getTemplateClass($name);
|
||||
|
||||
return $this->loadedWrappers[$cls] ??= new TemplateWrapper($this, $this->loadTemplate($cls, $name));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -598,6 +598,63 @@ EOF
|
||||
FilesystemHelper::removeDir($dir);
|
||||
}
|
||||
}
|
||||
|
||||
public function testLoadReusesTheWrapperOfAnAlreadyLoadedTemplate(): void
|
||||
{
|
||||
$twig = new Environment(new ArrayLoader(['index.twig' => 'x']));
|
||||
|
||||
$this->assertSame($twig->load('index.twig'), $twig->load('index.twig'));
|
||||
}
|
||||
|
||||
public function testRepeatedlyRemovingACacheDoesNotAccumulateWrappers(): void
|
||||
{
|
||||
$dir = sys_get_temp_dir().'/twig-wrapper-growth-test';
|
||||
if (is_dir($dir)) {
|
||||
FilesystemHelper::removeDir($dir);
|
||||
}
|
||||
mkdir($dir.'/cache', 0777, true);
|
||||
file_put_contents($dir.'/index.twig', 'x');
|
||||
|
||||
try {
|
||||
$twig = new Environment(new FilesystemLoader($dir), ['cache' => $dir.'/cache', 'auto_reload' => false]);
|
||||
for ($i = 0; $i < 10; ++$i) {
|
||||
$twig->load('index.twig');
|
||||
$twig->removeCache('index.twig');
|
||||
}
|
||||
$twig->load('index.twig');
|
||||
|
||||
$wrappers = (new \ReflectionObject($twig))->getProperty('loadedWrappers')->getValue($twig);
|
||||
$this->assertCount(1, $wrappers);
|
||||
} finally {
|
||||
FilesystemHelper::removeDir($dir);
|
||||
}
|
||||
}
|
||||
|
||||
public function testLoadFollowsALoaderThatResolvesANameDifferently(): void
|
||||
{
|
||||
$dir = sys_get_temp_dir().'/twig-loader-change-test';
|
||||
if (is_dir($dir)) {
|
||||
FilesystemHelper::removeDir($dir);
|
||||
}
|
||||
mkdir($dir.'/a', 0777, true);
|
||||
mkdir($dir.'/b', 0777, true);
|
||||
file_put_contents($dir.'/a/index.twig', 'a');
|
||||
file_put_contents($dir.'/b/index.twig', 'b');
|
||||
|
||||
try {
|
||||
$loader = new FilesystemLoader([$dir.'/a']);
|
||||
$twig = new Environment($loader, ['cache' => false]);
|
||||
|
||||
$this->assertSame('a', $twig->load('index.twig')->render([]));
|
||||
|
||||
// the loader now resolves the same name to another file
|
||||
$loader->prependPath($dir.'/b');
|
||||
|
||||
$this->assertSame('b', $twig->load('index.twig')->render([]));
|
||||
} finally {
|
||||
FilesystemHelper::removeDir($dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class EnvironmentTest_Extension_WithGlobals extends AbstractExtension
|
||||
|
||||
Reference in New Issue
Block a user