diff --git a/src/Rules/PdoStatementExecuteMethodRule.php b/src/Rules/PdoStatementExecuteMethodRule.php index 1917de2c..d57e7175 100644 --- a/src/Rules/PdoStatementExecuteMethodRule.php +++ b/src/Rules/PdoStatementExecuteMethodRule.php @@ -43,7 +43,7 @@ public function processNode(Node $methodCall, Scope $scope): array return []; } - if (PDOStatement::class !== $methodReflection->getDeclaringClass()->getName()) { + if (!(new \PHPStan\Type\ObjectType(PDOStatement::class))->isSuperTypeOf($scope->getType($methodCall->var))->yes()) { return []; } diff --git a/tests/default/Fixture/MyPdoStatement.php b/tests/default/Fixture/MyPdoStatement.php new file mode 100644 index 00000000..43a599a1 --- /dev/null +++ b/tests/default/Fixture/MyPdoStatement.php @@ -0,0 +1,13 @@ +analyse([__DIR__ . '/data/pdo-stmt-execute-subclassed.php'], [ + [ + 'Query expects placeholder :adaid, but it is missing from values given.', + 14, + ], + [ + 'Value :wrongParamName is given, but the query does not contain this placeholder.', + 14, + ], + [ + 'Query expects placeholder :adaid, but it is missing from values given.', + 18, + ], + ]); + } } diff --git a/tests/rules/data/pdo-stmt-execute-subclassed.php b/tests/rules/data/pdo-stmt-execute-subclassed.php new file mode 100644 index 00000000..5c615b2f --- /dev/null +++ b/tests/rules/data/pdo-stmt-execute-subclassed.php @@ -0,0 +1,27 @@ +prepare('SELECT email, adaid FROM ada WHERE adaid = :adaid'); + assert($stmt instanceof MyPdoStatement); + $stmt->execute(['wrongParamName' => 1]); // error: wrong param name + + $stmt = $pdo->prepare('SELECT email, adaid FROM ada WHERE adaid = :adaid'); + assert($stmt instanceof MyPdoStatement); + $stmt->execute(); // error: missing parameter + } + + public function noErrors(PDO $pdo): void + { + $stmt = $pdo->prepare('SELECT email, adaid FROM ada WHERE adaid = :adaid'); + assert($stmt instanceof MyPdoStatement); + $stmt->execute(['adaid' => 1]); // correct + } +}