Skip to content

Commit 4687a8f

Browse files
Etienne V. Labellestaabm
authored andcommitted
fix: preserve typed rows for PDO statements using bindValue() and execute()
1 parent 9a2d1ae commit 4687a8f

1 file changed

Lines changed: 26 additions & 4 deletions

File tree

src/Extensions/PdoStatementExecuteTypeSpecifyingExtension.php

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
use PHPStan\Analyser\TypeSpecifierAwareExtension;
1313
use PHPStan\Analyser\TypeSpecifierContext;
1414
use PHPStan\Reflection\MethodReflection;
15+
use PHPStan\Type\Constant\ConstantArrayType;
16+
use PHPStan\Type\Constant\ConstantIntegerType;
17+
use PHPStan\Type\Constant\ConstantStringType;
1518
use PHPStan\Type\MethodTypeSpecifyingExtension;
1619
use PHPStan\Type\Type;
1720
use staabm\PHPStanDba\PdoReflection\PdoStatementReflection;
@@ -62,9 +65,7 @@ private function inferStatementType(MethodReflection $methodReflection, MethodCa
6265
{
6366
$args = $methodCall->getArgs();
6467

65-
if (0 === \count($args)) {
66-
return null;
67-
}
68+
6869

6970
$stmtReflection = new PdoStatementReflection();
7071
$queryExpr = $stmtReflection->findPrepareQueryStringExpression($methodCall);
@@ -73,7 +74,28 @@ private function inferStatementType(MethodReflection $methodReflection, MethodCa
7374
}
7475

7576
$queryReflection = new QueryReflection();
76-
$parameterTypes = $queryReflection->resolveParameterTypes($args[0]->value, $scope);
77+
78+
79+
if (0 === \count($args)) {
80+
$parameterKeys = [];
81+
$parameterValues = [];
82+
83+
foreach ($stmtReflection->findPrepareBindCalls($methodCall) as $bindCall) {
84+
$bindArgs = $bindCall->getArgs();
85+
if (\count($bindArgs) >= 2) {
86+
$keyType = $scope->getType($bindArgs[0]->value);
87+
if ($keyType instanceof ConstantIntegerType || $keyType instanceof ConstantStringType) {
88+
$parameterKeys[] = $keyType;
89+
$parameterValues[] = $scope->getType($bindArgs[1]->value);
90+
}
91+
}
92+
}
93+
94+
$parameterTypes = new ConstantArrayType($parameterKeys, $parameterValues);
95+
} else {
96+
$parameterTypes = $queryReflection->resolveParameterTypes($args[0]->value, $scope);
97+
}
98+
7799
$queryStrings = $queryReflection->resolvePreparedQueryStrings($queryExpr, $parameterTypes, $scope);
78100

79101
$reflectionFetchType = QueryReflection::getRuntimeConfiguration()->getDefaultFetchMode();

0 commit comments

Comments
 (0)