Skip to content

Commit 4a95735

Browse files
authored
validate parameter count only with unnamed placeholders (#220)
1 parent 51eccf5 commit 4a95735

File tree

4 files changed

+42
-15
lines changed

4 files changed

+42
-15
lines changed

src/QueryReflection/PlaceholderValidation.php

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,23 @@ private function checkErrors(string $queryString, array $parameters): iterable
3737
}
3838

3939
$queryReflection = new QueryReflection();
40-
$placeholderCount = $queryReflection->countPlaceholders($queryString);
40+
if ($queryReflection->containsNamedPlaceholders($queryString, $parameters)) {
41+
yield from $this->validateNamedPlaceholders($queryString, $parameters);
4142

42-
yield from $this->checkParameterValues($queryString, $parameters, $placeholderCount);
43+
return;
44+
}
45+
46+
$placeholderCount = $queryReflection->countPlaceholders($queryString);
47+
yield from $this->validateUnnamedPlaceholders($parameters, $placeholderCount);
4348
}
4449

4550
/**
4651
* @param array<string|int, Parameter> $parameters
4752
*
4853
* @return iterable<string>
4954
*/
50-
private function checkParameterValues(string $queryString, array $parameters, int $placeholderCount): iterable
55+
private function validateUnnamedPlaceholders(array $parameters, int $placeholderCount): iterable
5156
{
52-
$queryReflection = new QueryReflection();
53-
5457
$parameterCount = \count($parameters);
5558
$minParameterCount = 0;
5659
foreach ($parameters as $parameter) {
@@ -82,11 +85,19 @@ private function checkParameterValues(string $queryString, array $parameters, in
8285
}
8386

8487
yield $placeholderExpectation.', '.$parameterActual.'.';
85-
86-
return;
8788
}
89+
}
8890

91+
/**
92+
* @param array<string|int, Parameter> $parameters
93+
*
94+
* @return iterable<string>
95+
*/
96+
private function validateNamedPlaceholders(string $queryString, array $parameters): iterable
97+
{
98+
$queryReflection = new QueryReflection();
8999
$namedPlaceholders = $queryReflection->extractNamedPlaceholders($queryString);
100+
90101
foreach ($namedPlaceholders as $namedPlaceholder) {
91102
if (!\array_key_exists($namedPlaceholder, $parameters)) {
92103
yield sprintf('Query expects placeholder %s, but it is missing from values given.', $namedPlaceholder);

src/QueryReflection/QueryReflection.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,26 @@ public function countPlaceholders(string $queryString): int
356356
return 0;
357357
}
358358

359+
/**
360+
* @param array<string|int, Parameter> $parameters
361+
*/
362+
public function containsNamedPlaceholders(string $queryString, array $parameters): bool
363+
{
364+
$namedPlaceholders = $this->extractNamedPlaceholders($queryString);
365+
366+
if ([] !== $namedPlaceholders) {
367+
return true;
368+
}
369+
370+
foreach ($parameters as $parameter) {
371+
if (null !== $parameter->name) {
372+
return true;
373+
}
374+
}
375+
376+
return false;
377+
}
378+
359379
/**
360380
* @return list<string>
361381
*/

tests/PdoStatementExecuteMethodRuleTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,19 @@ public function testParameterErrors(): void
4848
],
4949
*/
5050
[
51-
'Query expects 1 placeholder, but no values are given.',
51+
'Query expects placeholder :adaid, but it is missing from values given.',
5252
21,
5353
],
5454
[
5555
'Query expects 2 placeholders, but 1 value is given.',
5656
24,
5757
],
5858
[
59-
'Query expects 2 placeholders, but 1 value is given.',
59+
'Query expects placeholder :email, but it is missing from values given.',
6060
27,
6161
],
6262
[
63-
'Query expects 2 placeholders, but 1 value is given.',
63+
'Query expects placeholder :adaid, but it is missing from values given.',
6464
30,
6565
],
6666
[
@@ -72,7 +72,7 @@ public function testParameterErrors(): void
7272
36,
7373
],
7474
[
75-
'Query expects 1 placeholder, but 2 values are given.',
75+
'Value :email is given, but the query does not contain this placeholder.',
7676
38,
7777
],
7878
[

tests/SyntaxErrorInPreparedStatementMethodRuleTest.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,6 @@ public function testSyntaxErrorInQueryRule(): void
6161
'Query expects placeholder :name, but it is missing from values given.',
6262
307,
6363
],
64-
[
65-
'Query expects 2 placeholders, but 0-1 values are given.',
66-
307,
67-
],
6864
]);
6965
}
7066
}

0 commit comments

Comments
 (0)