@@ -50,12 +50,15 @@ public function prune()
5050 {
5151$ time =time ();
5252$ pruned =true ;
53+ $ getExpiry =true ;
5354
5455set_error_handler ($ this ->includeHandler );
5556try {
5657foreach (new \RecursiveIteratorIterator (new \RecursiveDirectoryIterator ($ this ->directory , \FilesystemIterator::SKIP_DOTS ), \RecursiveIteratorIterator::LEAVES_ONLY )as $ file ) {
5758try {
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+
9095foreach ($ idsas $ id ) {
9196if (null ===$ value =$ this ->values [$ id ] ??null ) {
9297$ missingIds [] =$ id ;
9398 }elseif ('N; ' ===$ value ) {
9499$ values [$ id ] =null ;
95- }elseif ($ valueinstanceof \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 ] =$ valueinstanceof LazyValue ?include $ value ->file :$ value ();
97103 }else {
98104$ values [$ id ] =$ value ;
99105 }
@@ -108,10 +114,18 @@ protected function doFetch(array $ids)
108114
109115set_error_handler ($ this ->includeHandler );
110116try {
117+ $ getExpiry =true ;
118+
111119foreach ($ missingIdsas $ k =>$ id ) {
112120try {
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+
115129if ($ now >=$ expiresAt ) {
116130 unset($ this ->values [$ id ],$ missingIds [$ k ]);
117131 }
@@ -140,7 +154,13 @@ protected function doHave($id)
140154set_error_handler ($ this ->includeHandler );
141155try {
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 ) {
145165return false ;
146166 }finally {
@@ -189,13 +209,16 @@ protected function doSave(array $values, $lifetime)
189209 }
190210
191211if (!$ 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
200223if ($ allowCompile ) {
201224 @opcache_invalidate ($ file ,true );
@@ -241,3 +264,16 @@ protected function doUnlink($file)
241264return @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+ }