@@ -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,21 @@ 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
+ if (!$ value instanceof LazyValue) {
102
+ // calling a Closure is for @deprecated BC and should be removed in Symfony 5.0
103
+ $ values [$ id ] = $ value ();
104
+ } elseif (false === $ values [$ id ] = include $ value ->file ) {
105
+ unset($ values [$ id ], $ this ->values [$ id ]);
106
+ $ missingIds [] = $ id ;
107
+ }
97
108
} else {
98
109
$ values [$ id ] = $ value ;
99
110
}
@@ -108,10 +119,18 @@ protected function doFetch(array $ids)
108
119
109
120
set_error_handler ($ this ->includeHandler );
110
121
try {
122
+ $ getExpiry = true ;
123
+
111
124
foreach ($ missingIds as $ k => $ id ) {
112
125
try {
113
126
$ file = $ this ->files [$ id ] ?? $ this ->files [$ id ] = $ this ->getFile ($ id );
114
- list ($ expiresAt , $ this ->values [$ id ]) = include $ file ;
127
+
128
+ if (\is_array ($ expiresAt = include $ file )) {
129
+ [$ expiresAt , $ this ->values [$ id ]] = $ expiresAt ;
130
+ } elseif ($ now < $ expiresAt ) {
131
+ $ this ->values [$ id ] = new LazyValue ($ file );
132
+ }
133
+
115
134
if ($ now >= $ expiresAt ) {
116
135
unset($ this ->values [$ id ], $ missingIds [$ k ]);
117
136
}
@@ -140,7 +159,13 @@ protected function doHave($id)
140
159
set_error_handler ($ this ->includeHandler );
141
160
try {
142
161
$ file = $ this ->files [$ id ] ?? $ this ->files [$ id ] = $ this ->getFile ($ id );
143
- list ($ expiresAt , $ value ) = include $ file ;
162
+ $ getExpiry = true ;
163
+
164
+ if (\is_array ($ expiresAt = include $ file )) {
165
+ [$ expiresAt , $ value ] = $ expiresAt ;
166
+ } elseif ($ this ->appendOnly ) {
167
+ $ value = new LazyValue ($ file );
168
+ }
144
169
} catch (\ErrorException $ e ) {
145
170
return false ;
146
171
} finally {
@@ -189,13 +214,16 @@ protected function doSave(array $values, $lifetime)
189
214
}
190
215
191
216
if (!$ isStaticValue ) {
192
- $ value = str_replace ("\n" , "\n " , $ value );
193
- $ value = "static function () { \n\n return {$ value }; \n\n} " ;
217
+ // We cannot use a closure here because of https://bugs.php.net/76982
218
+ $ value = str_replace ('\Symfony\Component\VarExporter\Internal \\' , '' , $ value );
219
+ $ value = "<?php \n\nnamespace Symfony\Component\VarExporter\Internal; \n\nreturn \$getExpiry ? {$ expiry } : {$ value }; \n" ;
220
+ } else {
221
+ $ value = "<?php return [ {$ expiry }, {$ value }]; \n" ;
194
222
}
195
223
196
224
$ file = $ this ->files [$ key ] = $ this ->getFile ($ key , true );
197
225
// 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 ;
226
+ $ ok = $ this ->write ($ file , $ value , self ::$ startTime - 10 ) && $ ok ;
199
227
200
228
if ($ allowCompile ) {
201
229
@opcache_invalidate ($ file , true );
@@ -241,3 +269,16 @@ protected function doUnlink($file)
241
269
return @unlink ($ file );
242
270
}
243
271
}
272
+
273
+ /**
274
+ * @internal
275
+ */
276
+ class LazyValue
277
+ {
278
+ public $ file ;
279
+
280
+ public function __construct ($ file )
281
+ {
282
+ $ this ->file = $ file ;
283
+ }
284
+ }
0 commit comments