背景
think-orm(db库)在处理长整型参数时会进行一次安全处理转换成浮点型,但php浮点数超过一定长度就会失去精准度变成科学计数,导致where条件匹配不上,这个问题目前覆盖thinkphp3到8全系;
解决方案
- 全局搜索 (float) $val[0] : $val[0] 找到如下图代码,不同版本可能位置不大一样,自行处理
- 修改成如下代码
php
/**
* 参数绑定
* 支持 ['name'=>'value','id'=>123] 对应命名占位符
* 或者 ['value',123] 对应问号占位符
* @access public
* @param array $bind 要绑定的参数列表
* @return void
* @throws BindParamException
*/
protected function bindValue(array $bind = []): void
{
foreach ($bind as $key => $val) {
// 占位符
$param = is_numeric($key) ? $key + 1 : ':' . $key;
if (is_array($val)) {
if (PDO::PARAM_INT == $val[1] && '' === $val[0]) {
$val[0] = 0;
} elseif (self::PARAM_FLOAT == $val[1]) {
// $val[0] = is_string($val[0]) ? (float) $val[0] : $val[0]; // 原代码
$val[0] = (is_string($val[0]) && !preg_match("/^\d+(\.\d+)?$/", $val[0])) ? (float) $val[0] : $val[0]; // 修复后的代码
$val[1] = PDO::PARAM_STR;
}
$result = $this->PDOStatement->bindValue($param, $val[0], $val[1]);
} else {
$result = $this->PDOStatement->bindValue($param, $val);
}
if (!$result) {
throw new BindParamException(
"Error occurred when binding parameters '{$param}'",
$this->config,
$this->getLastsql(),
$bind
);
}
}
}