我有一份工作申请表,管理员需要从某些用户 ID 列表中进行选择。该列表仅包含“雇主”类型的用户 ID,但是我想验证管理员输入,因此如果他手动插入不存在的 ID 或者与“雇主”类型不同的用户的 ID,则验证应该失败。我认为执行此操作的代码是:
new Zend_Validate_Db_RecordExists(
array(
'table' => 'users',
'field' => 'id',
'exclude' => "mode != 'employer'"
)
)
所以,我正在搜索表 users 中的所有记录,不包括那些 mode != 'employer' 的记录 - 如果存在这样的记录,其中 id 等于从输入中选取的记录,则它通过验证。但是,上面的代码不起作用 - 我必须执行 'exclude' => "mode = 'employer'"
,因此排除实际上等于 where 语句。我对这里逻辑的理解是错误的 - 有人能告诉我为什么吗?
PHP:5.2.17,Zend:1.10.4
编辑:(对@ro ko询问的评论,因为它可能会澄清事情)
请在此处找到表格和示例代码:http://pastebin.com/C7AXMNTZ 。根据我的理解,这应该对 Joker(是雇主)返回有效,但对 Kingpin(不是雇主)和 Poison Ivy(不在数据库中)返回 false - 正如你所看到的结果不是我所期望的。
最佳答案
A) '排除'=>“模式!='雇主'”
$id = new Zend_Form_Element_Select("id");
$id->setRegisterInArrayValidator(false);
$id->addValidator(new Zend_Validate_Db_RecordExists(array(
'table' => 'villains',
'field' => 'id',
'exclude' => "mode != 'employer'"
)));
产生以下查询:
SELECT `villains`.`id`
FROM `villains`
WHERE (`id` = :value) AND (mode != 'employer')
LIMIT 1
B) '排除'=>“模式='雇主'”
$id = new Zend_Form_Element_Select("id");
$id->setRegisterInArrayValidator(false);
$id->addValidator(new Zend_Validate_Db_RecordExists(array(
'table' => 'villains',
'field' => 'id',
'exclude' => "mode = 'employer'"
)));
产生以下查询:
SELECT `villains`.`id`
FROM `villains`
WHERE (`id` = :value) AND (mode = 'employer')
LIMIT 1
C) 'exclude' => array("field"=> "mode", "value"=> "employer")
$id = new Zend_Form_Element_Select("id");
$id->setRegisterInArrayValidator(false);
$id->addValidator(new Zend_Validate_Db_RecordExists(array(
'table' => 'villains',
'field' => 'id',
'exclude' => array(
"field" => "mode",
"value" => "employer"
)
)));
产生以下查询:
SELECT `villains`.`id`
FROM `villains`
WHERE (`id` = :value) AND (`mode` != 'employer')
LIMIT 1
结果
你想要B。它令人困惑,并且可以说组件的逻辑和行为是倒退的。尽管如此,您想要的行为来自示例 B。
附录
我们可以进行一个测试(我的意思是一起进行黑客攻击)来检查上述内容是否按预期工作。
test1 和 test2 都通过了,但是正如您从提供程序中看到的那样,它们都产生不同的结果。
class SO14706653Test extends PHPUnit_Framework_TestCase
{
/**
* @var Zend_Test_PHPUnit_Db_Connection
*/
public $dbConnection;
public function getRowCount($tableName) {
$query = "SELECT COUNT(*) FROM ".$this->dbConnection->quoteSchemaObject($tableName);
return (int) $this->dbConnection->getConnection()->query($query)->fetchColumn();
}
// hack a very quick setup for tests
public function setup() {
$app = new Zend_Application(APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini');
$app->bootstrap();
$dbAdapter = $app->getBootstrap()->getResource('db'); /* @var $db Zend_Db_Adapter_Pdo_Mysql */
$this->dbConnection = new Zend_Test_PHPUnit_Db_Connection($dbAdapter, 'unittests');
$dbAdapter->exec("CREATE TABLE IF NOT EXISTS `villains` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`mode` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1");
$dbAdapter->exec('DELETE FROM villains'); // clean out db data
$dbAdapter->exec("
INSERT INTO `villains` VALUES(1, 'Joker', 'employer');
INSERT INTO `villains` VALUES(2, 'Kingpin', '');
INSERT INTO `villains` VALUES(3, 'Penguin', '');
");
}
// ensure the above setup is working as expected
public function assertPreConditions() {
$this->assertEquals(3, $this->getRowCount('villains'));
}
public function provideTest1()
{
return [
// form data is valid? isRequired?
[['id' => '1'], false, false],
[['id' => '2'], true, false],
[['id' => '3'], true, false],
[['id' => ''], true, false],
[[], true, false],
[['id' => '856'], false, false],
[['id' => '856'], false, true],
[['id' => ''], false, true],
[[], false, true],
];
}
public function provideTest2()
{
return [
// form data is valid? isRequired?
[['id' => '1'], true, false],
[['id' => '2'], false, false],
[['id' => '3'], false, false],
[['id' => ''], true, false],
[[], true, false],
[['id' => '856'], false, false],
[['id' => '856'], false, true],
[['id' => ''], false, true],
[[], false, true],
];
}
/**
* @dataProvider provideTest1
*/
public function test1(array $data, $isValid, $isRequired)
{
$form = new Zend_Form();
$id = new Zend_Form_Element_Select("id");
$id->setRegisterInArrayValidator(false);
$id->addValidator(new Zend_Validate_Db_RecordExists(array(
'table' => 'villains',
'field' => 'id',
'exclude' => "mode != 'employer'"
)));
$id->setRequired($isRequired);
$form->addElement($id);
// produces the query
// SELECT `villains`.`id`
// FROM `villains`
// WHERE (`id` = :value) AND (mode != 'employer')
// LIMIT 1
$this->assertSame($isValid, $form->isValid($data));
}
/**
* @dataProvider provideTest2
*/
public function test2(array $data, $isValid, $isRequired)
{
$form = new Zend_Form();
$id = new Zend_Form_Element_Select("id");
$id->setRegisterInArrayValidator(false);
$id->addValidator(new Zend_Validate_Db_RecordExists(array(
'table' => 'villains',
'field' => 'id',
'exclude' => "mode = 'employer'"
)));
$id->setRequired($isRequired);
$form->addElement($id);
// produces the query
// SELECT `villains`.`id`
// FROM `villains`
// WHERE (`id` = :value) AND (mode = 'employer')
// LIMIT 1
$this->assertSame($isValid, $form->isValid($data));
}
}
关于php - Zend_Validate_Db_RecordExists 排除逻辑问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14706653/