RecordExists and NoRecordExists is not reusable for validate different values
AndrejAndb opened this issue · 3 comments
Custom modification in method for debug: https://github.com/zendframework/zend-validator/blob/master/src/Db/AbstractDb.php#L321
protected function query($value)
{
$sql = new Sql($this->getAdapter());
$select = $this->getSelect();
$statement = $sql->prepareStatementForSqlObject($select);
$parameters = $statement->getParameterContainer();
$parameters['where1'] = $value; // <- PROBLEM
echo $statement->getSql() . "\n"; // <- DEBUG
$result = $statement->execute();
return $result->current();
}
test case:
$validator = new RecordExists([
'table' => 'tags',
'field' => 'id',
'adapter' => $this->getEvent()->getApplication()->getServiceManager()->get('DBSiteAdapter')
]);
print_r($validator->isValid(1)); echo "\n";
print_r($validator->isValid(2)); echo "\n";
result:
SELECT "tags"."id" AS "id" FROM "tags" WHERE "id" = :where1
1
SELECT "tags"."id" AS "id" FROM "tags" WHERE "id" = :where2
PDO EXCEPTION: SQLSTATE[HY093]: Invalid parameter number: :where1
as we see, in next call we have :where2
instead :where1
Hm, I was found that problem occurs not for All PDO drivers. For sqlite:
- all fine, but for pgsql:
problem was present.
(Sorry, do not have time for continue analyze, I will fix it for me by implement alternative approach)
I will try to continue :)
source code of validator:
zend-validator/src/Db/AbstractDb.php
Lines 315 to 325 in 2868a94
protected function query($value)
{
$sql = new Sql($this->getAdapter());
$select = $this->getSelect();
$statement = $sql->prepareStatementForSqlObject($select);
$parameters = $statement->getParameterContainer();
$parameters['where1'] = $value;
$result = $statement->execute()
source code of https://github.com/zendframework/zend-db/blob/b1c79192c76b817062c1fa4e81ef2dcf1afea73e/src/Sql/AbstractSql.php#L136
if (! isset($this->instanceParameterIndex[$namedParameterPrefix])) {
$this->instanceParameterIndex[$namedParameterPrefix] = 1;
}
$expressionParamIndex = &$this->instanceParameterIndex[$namedParameterPrefix];
.....
$name = $namedParameterPrefix . $expressionParamIndex++;
so, for Select
Object we have ever-increased number postfix for named parameter markers: where1
, where2
, etc...
But for sqlite is Ok, because Zend\Db\Sql\Platform\Platform
has Select decorator for sqlite, and Platform
object was re-instantiated for each 'validation call', and in this case we have that $this->instanceParameterIndex
reset each time
:)
I am not sure that it is must be fixed on zend-db
side, looks like better implement some alternative approach for validator :)
This repository has been closed and moved to laminas/laminas-validator; a new issue has been opened at laminas/laminas-validator#16.