@@ -50,12 +50,15 @@ public function prune()
50
50
{
51
51
$ time = time ();
52
52
$ pruned = true ;
53
+ $ getExpiry = true ;
53
54
54
55
set_error_handler ($ this ->includeHandler );
55
56
try {
56
57
foreach (new \RecursiveIteratorIterator (new \RecursiveDirectoryIterator ($ this ->directory , \FilesystemIterator::SKIP_DOTS ), \RecursiveIteratorIterator::LEAVES_ONLY ) as $ file ) {
57
58
try {
58
- list ($ expiresAt ) = include $ file ;
59
+ if (\is_array ($ expiresAt = include $ file )) {
60
+ $ expiresAt = $ expiresAt [0 ];
61
+ }
59
62
} catch (\ErrorException $ e ) {
60
63
$ expiresAt = $ time ;
61
64
}
@@ -87,13 +90,16 @@ protected function doFetch(array $ids)
87
90
$ values = [];
88
91
89
92
begin:
93
+ $ getExpiry = false ;
94
+
90
95
foreach ($ ids as $ id ) {
91
96
if (null === $ value = $ this ->values [$ id ] ?? null ) {
92
97
$ missingIds [] = $ id ;
93
98
} elseif ('N; ' === $ value ) {
94
99
$ 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 ();
97
103
} else {
98
104
$ values [$ id ] = $ value ;
99
105
}
@@ -108,10 +114,18 @@ protected function doFetch(array $ids)
108
114
109
115
set_error_handler ($ this ->includeHandler );
110
116
try {
117
+ $ getExpiry = true ;
118
+
111
119
foreach ($ missingIds as $ k => $ id ) {
112
120
try {
113
121
$ 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
+
115
129
if ($ now >= $ expiresAt ) {
116
130
unset($ this ->values [$ id ], $ missingIds [$ k ]);
117
131
}
@@ -140,7 +154,13 @@ protected function doHave($id)
140
154
set_error_handler ($ this ->includeHandler );
141
155
try {
142
156
$ 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
+ }
144
164
} catch (\ErrorException $ e ) {
145
165
return false ;
146
166
} finally {
@@ -189,13 +209,16 @@ protected function doSave(array $values, $lifetime)
189
209
}
190
210
191
211
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" ;
194
217
}
195
218
196
219
$ file = $ this ->files [$ key ] = $ this ->getFile ($ key , true );
197
220
// 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 ;
199
222
200
223
if ($ allowCompile ) {
201
224
@opcache_invalidate ($ file , true );
@@ -241,3 +264,16 @@ protected function doUnlink($file)
241
264
return @unlink ($ file );
242
265
}
243
266
}
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