为什么 PDO 将我的 bool(false) 参数转换为 string('')?

问题描述 投票:0回答:4

我在安装新的 MariaDB 10.5.8 时遇到问题。

STRICT_TRANS_TABLES
已设置,当我尝试使用
$sql
时:

'INSERT INTO test (flag) VALUES (?)'

(其中

flag
定义为
tinyint(1)
),
var_dump($params)
显示为:

array(1) {
  [0]=>
  bool(false)
}

我收到这条消息:

Incorrect integer value: '' for column `mydb`.`test`.`flag` at row 1

如果我这样做:

'INSERT INTO test (flag) VALUES (false)'

没有参数,它按预期工作。

这就是我连接数据库的方式:

$this->PDO = new PDO('mysql:host=' . DB_SERVER . ';dbname=' . DB_NAME . ';charset=utf8mb4', DB_USER, DB_PASSWORD, [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
    PDO::ATTR_STRINGIFY_FETCHES  => false,
]);

$this->PDO->query("SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'");

这就是我将查询/参数发送到 MariaDB 的方式:

$stmt = self::$_instance->PDO->prepare($sql);
$stmt->execute($params);

如果我尝试插入

true
而不是
false
,一切正常。
true
正在沿线某处转换为
1
,并且
false
转换为
''
。我做错了什么?

php mysql pdo mariadb
4个回答
8
投票

所有值都被视为 PDO::PARAM_STR

https://www.php.net/manual/en/pdostatement.execute.php

execute()
方法不允许您指定变量的类型。它总是转换为字符串,这就是为什么你会得到奇怪的结果:

php > var_dump((string) true);
string(1) "1"

php > var_dump((string) false);
string(0) ""

您可以使用 PDOStatement::bindValue() 指定值的类型:

$statement->bindValue('some_bool', true, PDO::PARAM_INT);

请注意,MySQL 缺少“真正的”布尔类型,这就是为什么我推荐

PDO::PARAM_INT
而不是
PDO::PARAM_BOOL


7
投票

一个更简单的解决方案就是预先将布尔值转换为 int

$stmt = $PDO->prepare('INSERT INTO test (flag) VALUES (?)');
$stmt->execute([(int)$flag]);

1
投票

这是一个快速片段,可以解决 pdo 参数中布尔值转换为空字符串的问题

$params = array_map(fn($param) => is_bool($param) ? intval($param) : $param, $params);

0
投票

当我在数据库中关闭@@mode STRICT_TRANS_TABLES时,这些值(1或空字符串)起作用 - 它们作为1或0插入到tinyint(1)类型的mysql列中。

© www.soinside.com 2019 - 2024. All rights reserved.