diff --git a/.phpunit-phpstan-dba.cache b/.phpunit-phpstan-dba.cache index db943e0b6..c5ca5fe6b 100644 --- a/.phpunit-phpstan-dba.cache +++ b/.phpunit-phpstan-dba.cache @@ -2349,6 +2349,11 @@ Simulated query: SELECT email, adaid FROM ada . WHERE email=\'my_other_table\' L )), ), ), + 'SELECT email, adaid, gesperrt, freigabe1u1 FROM ada + WHERE (gesperrt=\'1\' AND freigabe1u1=1) OR (gesperrt=\'1\' AND freigabe1u1=0)' => + array ( + 'error' => NULL, + ), 'SELECT email, adaid, gesperrt, freigabe1u1 FROM ada WHERE email=\'my_other_table\' LIMIT 1' => array ( 'error' => NULL, @@ -2787,6 +2792,14 @@ Simulated query: SELECT email, adaid, gesperrt, freigabe1u1 FROM ada . WHERE ema 'code' => 1054, )), ), + 'SELECT email, adaid, gesperrt, freigabe1u1 FROM ada WHERE asdsa=?' => + array ( + 'error' => + staabm\PHPStanDba\Error::__set_state(array( + 'message' => 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL/MariaDB server version for the right syntax to use near \'? LIMIT 0\' at line 1', + 'code' => 1064, + )), + ), 'SELECT email, adaid, gesperrt, freigabe1u1 FROM ada WHERE email = \'webmaster@example.org\'' => array ( 'error' => NULL, @@ -3017,5 +3030,13 @@ Simulated query: SELECT email, adaid, gesperrt, freigabe1u1 FROM ada . WHERE ema array ( 'error' => NULL, ), + 'SELECT email, adaid, gesperrt, freigabe1u1 FROM ada WHERE gesperrt=?' => + array ( + 'error' => + staabm\PHPStanDba\Error::__set_state(array( + 'message' => 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL/MariaDB server version for the right syntax to use near \'? LIMIT 0\' at line 1', + 'code' => 1064, + )), + ), ), ); \ No newline at end of file diff --git a/src/QueryReflection/QueryReflection.php b/src/QueryReflection/QueryReflection.php index 18f60d271..8a6b9bc10 100644 --- a/src/QueryReflection/QueryReflection.php +++ b/src/QueryReflection/QueryReflection.php @@ -7,7 +7,6 @@ use PhpParser\Node\Expr; use PhpParser\Node\Expr\BinaryOp\Concat; use PHPStan\Analyser\Scope; -use PHPStan\ShouldNotHappenException; use PHPStan\Type\Constant\ConstantArrayType; use PHPStan\Type\Constant\ConstantIntegerType; use PHPStan\Type\Constant\ConstantStringType; @@ -249,12 +248,7 @@ public function countPlaceholders(string $queryString): int return $numPlaceholders; } - $numPlaceholders = preg_match_all(self::REGEX_PLACEHOLDER, $queryString); - if (false === $numPlaceholders || $numPlaceholders < 0) { - throw new ShouldNotHappenException(); - } - - return $numPlaceholders; + return \count($this->extractNamedPlaceholders($queryString)); } /** @@ -270,7 +264,7 @@ public function extractNamedPlaceholders(string $queryString): array } if (preg_match_all(self::REGEX_PLACEHOLDER, $queryString, $matches) > 0) { - return $matches[0]; + return array_unique($matches[0]); } return []; diff --git a/tests/data/syntax-error-in-prepared-statement.php b/tests/data/syntax-error-in-prepared-statement.php index 88a1b7a75..8b32455c5 100644 --- a/tests/data/syntax-error-in-prepared-statement.php +++ b/tests/data/syntax-error-in-prepared-statement.php @@ -136,4 +136,11 @@ public function placeholderValidation(Connection $connection) $connection->preparedQuery($query, [':gesperrt' => 1]); } + + public function samePlaceholderMultipleTimes(Connection $connection) + { + $query = 'SELECT email, adaid, gesperrt, freigabe1u1 FROM ada + WHERE (gesperrt=:gesperrt AND freigabe1u1=1) OR (gesperrt=:gesperrt AND freigabe1u1=0)'; + $connection->preparedQuery($query, [':gesperrt' => 1]); + } }