1818 */
1919final class StreamWrapper implements StreamWrapperInterface
2020{
21+ /**
22+ * Bitmask constant passed by PHP's Zend Engine when a stream is opened by include/require.
23+ */
24+ public const STREAM_OPEN_FOR_INCLUDE = 128 ;
25+
2126 /**
2227 * Context resource provided by PHP stream subsystem.
2328 *
@@ -195,6 +200,12 @@ public function stream_open(string $path, string $mode, int $options, ?string &$
195200 return $ this ->openDirectHandle ($ path , $ mode );
196201 }
197202
203+ $ isInclude = ($ options & self ::STREAM_OPEN_FOR_INCLUDE ) !== 0 ;
204+ if (! $ isInclude ) {
205+ return $ this ->openDirectHandle ($ path , $ mode );
206+ }
207+
208+
198209 if (! str_ends_with (strtolower ($ path ), '.php ' )) {
199210 return $ this ->openDirectHandle ($ path , $ mode );
200211 }
@@ -204,20 +215,13 @@ public function stream_open(string $path, string $mode, int $options, ?string &$
204215 }
205216
206217 $ normalizedRaw = str_replace ('\\' , '/ ' , $ path );
207-
208218 if (! PathMatcher::mayPathBeIncluded ($ normalizedRaw )) {
209219 return $ this ->openDirectHandle ($ path , $ mode );
210220 }
211221
212- if (isset (self ::$ appFileDecisionCache [$ normalizedRaw ])) {
213- if (! self ::$ appFileDecisionCache [$ normalizedRaw ]) {
214- return $ this ->openDirectHandle ($ path , $ mode );
215- }
216- }
217-
218222 self ::unregister ();
219- $ exists = (bool ) self ::silent (fn () => file_exists ($ path ));
220- $ resolvedPath = $ exists ? self ::silent (fn () => realpath ($ path )) : false ;
223+ $ exists = (bool ) self ::silent (fn () => file_exists ($ path ));
224+ $ resolvedPath = $ exists ? self ::silent (fn () => realpath ($ path )) : false ;
221225 self ::register ();
222226
223227 if (! $ exists || $ resolvedPath === false ) {
@@ -266,7 +270,7 @@ private function openDirectHandle(string $targetFile, string $mode): bool
266270 {
267271 self ::unregister ();
268272 /** @var resource|false $handle */
269- $ handle = self ::silent (fn () => fopen ($ targetFile , $ mode ));
273+ $ handle = self ::silent (fn () => fopen ($ targetFile , $ mode ));
270274 $ this ->handle = $ handle !== false ? $ handle : null ;
271275 self ::register ();
272276
@@ -416,7 +420,7 @@ public function url_stat(string $path, int $flags): array|false
416420
417421 self ::unregister ();
418422 /** @var array<int|string, int>|false $result */
419- $ result = self ::silent (fn () => stat ($ path ));
423+ $ result = self ::silent (fn () => stat ($ path ));
420424 self ::register ();
421425
422426 if ($ result !== false ) {
@@ -442,11 +446,11 @@ public function stream_metadata(string $path, int $option, mixed $value): bool
442446 $ valueArray = \is_array ($ value ) ? $ value : [];
443447 $ time = $ valueArray [0 ] ?? time ();
444448 $ atime = $ valueArray [1 ] ?? $ time ;
445- $ result = (bool ) self ::silent (fn () => touch ($ path , (int ) $ time , (int ) $ atime ));
449+ $ result = (bool ) self ::silent (fn () => touch ($ path , (int ) $ time , (int ) $ atime ));
446450 } elseif ($ option === STREAM_META_ACCESS ) {
447451 /** @var int $mode */
448452 $ mode = \is_int ($ value ) ? $ value : 0777 ;
449- $ result = (bool ) self ::silent (fn () => chmod ($ path , $ mode ));
453+ $ result = (bool ) self ::silent (fn () => chmod ($ path , $ mode ));
450454 }
451455 self ::register ();
452456
@@ -457,7 +461,7 @@ public function dir_opendir(string $path, int $options): bool
457461 {
458462 self ::unregister ();
459463 /** @var resource|false $dh */
460- $ dh = self ::silent (fn () => opendir ($ path ));
464+ $ dh = self ::silent (fn () => opendir ($ path ));
461465 $ this ->dirHandle = $ dh !== false ? $ dh : null ;
462466 self ::register ();
463467
@@ -500,7 +504,7 @@ public function mkdir(string $path, int $mode, int $options): bool
500504 unset(self ::$ statCache [$ normalized ], self ::$ staticNegativeStatCache [$ normalized ]);
501505
502506 self ::unregister ();
503- $ result = (bool ) self ::silent (fn () => mkdir ($ path , $ mode , ($ options & STREAM_MKDIR_RECURSIVE ) !== 0 ));
507+ $ result = (bool ) self ::silent (fn () => mkdir ($ path , $ mode , ($ options & STREAM_MKDIR_RECURSIVE ) !== 0 ));
504508 self ::register ();
505509
506510 return $ result ;
@@ -512,7 +516,7 @@ public function rmdir(string $path, int $options): bool
512516 unset(self ::$ statCache [$ normalized ], self ::$ staticNegativeStatCache [$ normalized ]);
513517
514518 self ::unregister ();
515- $ result = (bool ) self ::silent (fn () => rmdir ($ path ));
519+ $ result = (bool ) self ::silent (fn () => rmdir ($ path ));
516520 self ::register ();
517521
518522 return $ result ;
@@ -524,7 +528,7 @@ public function unlink(string $path): bool
524528 unset(self ::$ statCache [$ normalized ], self ::$ staticNegativeStatCache [$ normalized ]);
525529
526530 self ::unregister ();
527- $ result = (bool ) self ::silent (fn () => unlink ($ path ));
531+ $ result = (bool ) self ::silent (fn () => unlink ($ path ));
528532 self ::register ();
529533
530534 return $ result ;
@@ -542,7 +546,7 @@ public function rename(string $pathFrom, string $pathTo): bool
542546 );
543547
544548 self ::unregister ();
545- $ result = (bool ) self ::silent (fn () => rename ($ pathFrom , $ pathTo ));
549+ $ result = (bool ) self ::silent (fn () => rename ($ pathFrom , $ pathTo ));
546550 self ::register ();
547551
548552 return $ result ;
@@ -559,7 +563,7 @@ public function rename(string $pathFrom, string $pathTo): bool
559563 */
560564 private static function silent (callable $ callback ): mixed
561565 {
562- set_error_handler (fn () => true );
566+ set_error_handler (fn () => true );
563567
564568 try {
565569 return $ callback ();
@@ -632,7 +636,7 @@ private function openCachedStream(string $resolvedPath, string $mode): bool
632636 {
633637 $ cacheDir = self ::$ cacheDir ;
634638 if (! is_dir ($ cacheDir )) {
635- self ::silent (fn () => mkdir ($ cacheDir , 0777 , true ));
639+ self ::silent (fn () => mkdir ($ cacheDir , 0777 , true ));
636640 }
637641
638642 $ cachedFile = CacheManager::getCachedFilePath ($ resolvedPath );
0 commit comments