[英]How to manually escape a boolean value for a mySQL Database insert in CakePHP?
i'm having the following code: 我有以下代码:
/** @var DboSource $db */
$db = $this->getDataSource();
var_dump($db->value($open, 'boolean'));
die;
$this->query(
'INSERT INTO foo(`client_id`, `open`, `modified`, `created`) VALUES(:clientId, :open, NOW(), NOW()) ON DUPLICATE KEY UPDATE modified = now();',
[
':clientId' => $db->value($clientId, 'integer'),
':open' => $db->value($open, 'boolean')
]
);
$open
is a boolean value, the 'open'
-column is defined as tinyint(1)
. $open
是一个布尔值, 'open'
-column定义为tinyint(1)
。 When wrapping $open with $db->value($open, 'boolean')
the result is '1'
, '0'
(see the single quotes). 当用
$db->value($open, 'boolean')
包装$ open时,结果为'1'
, '0'
(请参见单引号)。
Unfortunately this output leads to a new record with open = false
(as '1'
is not properly inserted as true
) 不幸的是,此输出导致
open = false
的新记录(因为未正确将true
插入'1'
)
If I use $db->boolean($open)
as option, everything's working correctly. 如果我使用
$db->boolean($open)
作为选项,则一切正常。
But I think, $db->value()
should do the same job as well? 但是我认为
$db->value()
应该做同样的工作吗?
Looking at when and how DboSource::value()
is being used internally, this is the expected behavior. 查看何时以及如何在内部使用
DboSource::value()
,这是预期的行为。 If it wouldn't do what it does, then values wouldn't get prepared properly for Model::save()
operations. 如果它不做它所做的事情,那么就不会为
Model::save()
操作正确准备值。
DboSource::value()
internally passes the "booleanized" value ( DboSource::boolean($value, true)
this already adds quotes) to PDO::quote()
, where the value is going to be quoted anyways no matter what, ie 0
, 1
, '0'
, '1'
, true
, or false
, it will always return a quoted value, that is '0'
, '1'
or even ''
(for false
, which is equal to 0
). DboSource::value()
内部将“ booleanized”值( DboSource::boolean($value, true)
已将引号引起来)传递给PDO::quote()
,无论如何该值都将被引用,即0
, 1
, '0'
, '1'
, true
或false
,这将始终返回引述的值,即'0'
, '1'
或甚至''
(为false
,这是等于0
)。
The problem with your code is, that values passed to the second argument of Model::query()
are finally being passed to PDOStatement::execute()
( .../DboSource.php#L458 ), which treats all values as strings and escapes them accordingly, so finally in your query a '1'
will end up as '\\'1\\''
, hence the problems. 您的代码的问题是,传递给
Model::query()
的第二个参数的值最终将传递给PDOStatement::execute()
( ... / DboSource.php#L458 ),它将所有值视为字符串并相应地对其进行转义,因此最终在您的查询中, '1'
将以'\\'1\\''
结尾,因此出现了问题。
TL;DR TL; DR
This seems to be the expected behavior, it's just poorly documented. 这似乎是预期的行为,但文献记录很少。 So when using the second argument of
Model::query()
, sanitize the values if necessary (ie cast to integers, booleans, strings, etc), but do not escape them, escape them only when you manually insert them in the actual query string ( which should however be avoided whenever possible )! 因此,当使用
Model::query()
的第二个参数时,如有必要,对值进行清理(即,转换为整数,布尔值,字符串等),但不要对其进行转义,仅当您在实际查询中手动插入它们时才对它们进行转义字符串( 但是应尽可能避免使用 )!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.