如何在 CakePHP 中手动转义 mySQL 数据库插入的布尔值?

How to manually escape a boolean value for a mySQL Database insert in CakePHP?

我有以下代码:

  /** @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 是布尔值,'open' 列定义为 tinyint(1)。当用 $db->value($open, 'boolean') 包装 $open 时,结果是 '1''0'(见单引号)。

不幸的是,此输出导致新记录 open = false(因为 '1' 未正确插入为 true

如果我使用 $db->boolean($open) 作为选项,一切正常。

不过我想,$db->value()也应该做同样的工作吧?

查看 DboSource::value() 在内部使用的时间和方式,这是预期的行为。如果它不做它做的事情,那么值就不会为 Model::save() 操作做好准备。

DboSource::value() 在内部将 "booleanized" 值(DboSource::boolean($value, true) 这已经添加了引号)传递给 PDO::quote(),无论如何都会引用该值,即 01'0''1'truefalse,它总是 return 引用值,即 '0''1' 甚至 ''(对于 false,等于 0)。

您的代码的问题是,传递给 Model::query() 的第二个参数的值最终被传递给 PDOStatement::execute() (.../DboSource.php#L458),它将所有值视为字符串并转义因此,最终在您的查询中,'1' 将以 '\'1\'' 结束,因此出现了问题。

TL;DR

这似乎是预期的行为,只是记录不完整。因此,当使用 Model::query() 的第二个参数时,必要时清理值(即转换为整数、布尔值、字符串等),但不要转义它们,仅当您手动将它们插入实际查询字符串时才转义它们(但应尽可能避免)!