From 7650ac8910df398534540dd5043e0ddaa1e00429 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 14 Jun 2026 08:10:24 +0200 Subject: [PATCH 1/3] Consider `is_file($path)` before checking `require $path` --- src/Rules/Keywords/RequireFileExistsRule.php | 22 +++++++++++++++++++ .../Keywords/RequireFileExistsRuleTest.php | 5 +++++ .../Keywords/data/include-in-file-exists.php | 9 ++++++++ 3 files changed, 36 insertions(+) create mode 100644 tests/PHPStan/Rules/Keywords/data/include-in-file-exists.php diff --git a/src/Rules/Keywords/RequireFileExistsRule.php b/src/Rules/Keywords/RequireFileExistsRule.php index b0d4def309..b47817e4d6 100644 --- a/src/Rules/Keywords/RequireFileExistsRule.php +++ b/src/Rules/Keywords/RequireFileExistsRule.php @@ -3,7 +3,10 @@ namespace PHPStan\Rules\Keywords; use PhpParser\Node; +use PhpParser\Node\Arg; +use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Expr\Include_; +use PhpParser\Node\Name\FullyQualified; use PHPStan\Analyser\Scope; use PHPStan\DependencyInjection\AutowiredParameter; use PHPStan\DependencyInjection\RegisteredRule; @@ -41,6 +44,10 @@ public function getNodeType(): string public function processNode(Node $node, Scope $scope): array { + if ($this->isInFileExists($node, $scope)) { + return []; + } + $errors = []; $paths = $this->resolveFilePaths($node, $scope); @@ -140,4 +147,19 @@ private function resolveFilePaths(Include_ $node, Scope $scope): array return $paths; } + private function isInFileExists(Include_ $node, Scope $scope): bool + { + foreach (['file_exists', 'is_file'] as $funcName) { + $expr = new FuncCall(new FullyQualified($funcName), [ + new Arg($node->expr), + ]); + + if ($scope->getType($expr)->isTrue()->yes()) { + return true; + } + } + + return false; + } + } diff --git a/tests/PHPStan/Rules/Keywords/RequireFileExistsRuleTest.php b/tests/PHPStan/Rules/Keywords/RequireFileExistsRuleTest.php index 732819b506..6599e0defe 100644 --- a/tests/PHPStan/Rules/Keywords/RequireFileExistsRuleTest.php +++ b/tests/PHPStan/Rules/Keywords/RequireFileExistsRuleTest.php @@ -136,4 +136,9 @@ public function testBug12203(): void ]); } + public function testInFileExists(): void + { + $this->analyse([__DIR__ . '/data/include-in-file-exists.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Keywords/data/include-in-file-exists.php b/tests/PHPStan/Rules/Keywords/data/include-in-file-exists.php new file mode 100644 index 0000000000..74e271d330 --- /dev/null +++ b/tests/PHPStan/Rules/Keywords/data/include-in-file-exists.php @@ -0,0 +1,9 @@ + Date: Sun, 14 Jun 2026 08:54:21 +0200 Subject: [PATCH 2/3] add test --- .../PHPStan/Rules/Keywords/data/include-in-file-exists.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/PHPStan/Rules/Keywords/data/include-in-file-exists.php b/tests/PHPStan/Rules/Keywords/data/include-in-file-exists.php index 74e271d330..b65dda5357 100644 --- a/tests/PHPStan/Rules/Keywords/data/include-in-file-exists.php +++ b/tests/PHPStan/Rules/Keywords/data/include-in-file-exists.php @@ -7,3 +7,9 @@ if (is_file(__DIR__ . '/../vendor/autoload.php')) { require __DIR__ . '/../vendor/autoload.php'; } + +foreach ([__DIR__ . '/../../autoload.php', __DIR__ . '/../autoload.php', __DIR__ . '/vendor/autoload.php'] as $file) { + if (file_exists($file)) { + require $file; + } +} From 6d16aa73c267683bb6faf253e63284ea458390f2 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 14 Jun 2026 08:55:56 +0200 Subject: [PATCH 3/3] Update include-in-file-exists.php --- .../Rules/Keywords/data/include-in-file-exists.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/PHPStan/Rules/Keywords/data/include-in-file-exists.php b/tests/PHPStan/Rules/Keywords/data/include-in-file-exists.php index b65dda5357..f3b1e22633 100644 --- a/tests/PHPStan/Rules/Keywords/data/include-in-file-exists.php +++ b/tests/PHPStan/Rules/Keywords/data/include-in-file-exists.php @@ -13,3 +13,11 @@ require $file; } } + +if (file_exists(__DIR__ . '/vendor/autoload.php')) { + require __DIR__ . '/vendor/autoload.php'; +} elseif (file_exists(__DIR__ . '/../../autoload.php')) { + require __DIR__ . '/../../autoload.php'; +} else { + throw new \RuntimeException("Unable to locate vendor/autoload.php"); +}