Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cb43eee

Browse files
[Cache] work aroung PHP memory leak
1 parent 2fdfa1a commit cb43eee

File tree

1 file changed

+44
-8
lines changed

1 file changed

+44
-8
lines changed

src/Symfony/Component/Cache/Traits/PhpFilesTrait.php

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,15 @@ public function prune()
5050
{
5151
$time = time();
5252
$pruned = true;
53+
$getExpiry = true;
5354

5455
set_error_handler($this->includeHandler);
5556
try {
5657
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->directory, \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
5758
try {
58-
list($expiresAt) = include $file;
59+
if (\is_array($expiresAt = include $file)) {
60+
$expiresAt = $expiresAt[0];
61+
}
5962
} catch (\ErrorException $e) {
6063
$expiresAt = $time;
6164
}
@@ -87,13 +90,16 @@ protected function doFetch(array $ids)
8790
$values = [];
8891

8992
begin:
93+
$getExpiry = false;
94+
9095
foreach ($ids as $id) {
9196
if (null === $value = $this->values[$id] ?? null) {
9297
$missingIds[] = $id;
9398
} elseif ('N;' === $value) {
9499
$values[$id] = null;
95-
} elseif ($value instanceof \Closure) {
96-
$values[$id] = $value();
100+
} elseif (\is_object($value)) {
101+
// calling a Closure is for @deprecated BC and should be removed in Symfony 5.0
102+
$values[$id] = $value instanceof LazyValue ? include $value->file : $value();
97103
} else {
98104
$values[$id] = $value;
99105
}
@@ -108,10 +114,18 @@ protected function doFetch(array $ids)
108114

109115
set_error_handler($this->includeHandler);
110116
try {
117+
$getExpiry = true;
118+
111119
foreach ($missingIds as $k => $id) {
112120
try {
113121
$file = $this->files[$id] ?? $this->files[$id] = $this->getFile($id);
114-
list($expiresAt, $this->values[$id]) = include $file;
122+
123+
if (\is_array($expiresAt = include $file)) {
124+
[$expiresAt, $this->values[$id]] = $expiresAt;
125+
} elseif ($now < $expiresAt) {
126+
$this->values[$id] = new LazyValue($file);
127+
}
128+
115129
if ($now >= $expiresAt) {
116130
unset($this->values[$id], $missingIds[$k]);
117131
}
@@ -140,7 +154,13 @@ protected function doHave($id)
140154
set_error_handler($this->includeHandler);
141155
try {
142156
$file = $this->files[$id] ?? $this->files[$id] = $this->getFile($id);
143-
list($expiresAt, $value) = include $file;
157+
$getExpiry = true;
158+
159+
if (\is_array($expiresAt = include $file)) {
160+
[$expiresAt, $value] = $expiresAt;
161+
} elseif ($this->appendOnly) {
162+
$value = new LazyValue($file);
163+
}
144164
} catch (\ErrorException $e) {
145165
return false;
146166
} finally {
@@ -189,13 +209,16 @@ protected function doSave(array $values, $lifetime)
189209
}
190210

191211
if (!$isStaticValue) {
192-
$value = str_replace("\n", "\n ", $value);
193-
$value = "static function () {\n\n return {$value};\n\n}";
212+
// We cannot use a closure here because of https://bugs.php.net/76982
213+
$value = str_replace('\Symfony\Component\VarExporter\Internal\\', '', $value);
214+
$value = "<?php\n\nnamespace Symfony\Component\VarExporter\Internal;\n\nreturn \$getExpiry ? {$expiry} : {$value};\n";
215+
} else {
216+
$value = "<?php return [{$expiry}, {$value}];\n";
194217
}
195218

196219
$file = $this->files[$key] = $this->getFile($key, true);
197220
// Since OPcache only compiles files older than the script execution start, set the file's mtime in the past
198-
$ok = $this->write($file, "<?php return [{$expiry}, {$value}];\n", self::$startTime - 10) && $ok;
221+
$ok = $this->write($file, $value, self::$startTime - 10) && $ok;
199222

200223
if ($allowCompile) {
201224
@opcache_invalidate($file, true);
@@ -241,3 +264,16 @@ protected function doUnlink($file)
241264
return @unlink($file);
242265
}
243266
}
267+
268+
/**
269+
* @internal
270+
*/
271+
class LazyValue
272+
{
273+
public $file;
274+
275+
public function __construct($file)
276+
{
277+
$this->file = $file;
278+
}
279+
}

0 commit comments

Comments
 (0)