问题描述
典型的手机号问题,数据库varchar, 手机号加了索引,但是php传参传intpublic function getByPhone($phone){
return $this->userFollow
->where('phone', $phone)
->get();
}$this->getByPhone(13845678889); //不走索引打印出的原生sql是:string(48) "select * from zp_user_follow where phone = ?" array(1) { [0]=> int(15000475201) }
$this->getByPhone('13845678889'); //走索引打印出的原生sql是:string(48) "select * from zp_user_follow where phone = ?" array(1) { [0]=> string(11) "15000475201" }
问题出现的环境背景及自己尝试过哪些方法
在变量前面加入类型public function getByPhone(string $phone){
return $this->userFollow
->where('phone', $phone)
->get();
}这是方式是强制约束,但是程序员如果不写呢?如果传的是个数组,数组里是['phone' => 13845678889];怎么解决?
相关代码
laravel 底层是pdo,pdo绑定参数的底层代码,是会判断第三个参数使用的类型public function bindValues($statement, $bindings){
foreach ($bindings as $key => $value) {
$statement->bindValue(
is_string($key) ? $key : $key + 1, $value,
is_int($value) || is_float($value) ? PDO::PARAM_INT : PDO::PARAM_STR
);
}
}
你期待的结果是什么?实际看到的错误信息又是什么?
有没有办法,在不改底层laravel,就算程序员写错了,可以在查询的时候,自动解析查询参数的类型和数据库字段类型进行匹配,也能正确保证走索引,如果没有办法,只能把问题抛给程序员?让他们注意写代码的时候,声明查询参数的类型要和数据库一致?如果他们忘记了怎么办?问题在放大一点,假如生成环境数据量大,不走索引,全表扫描,如果因为这个问题,导致了慢sql,生成环境出bug, 扣绩效?批评?
是把问题抛给人本身,如果抛给人本身,那么是我们习惯约定大于配置,给自己找个不想用技术手段解决的理由?还是可以用技术手段解决,就得改底层了,但是laravel底层为什么这么实现呢?它本身就把问题抛给我们开发者,需要我们执行约定?,希望有人解惑啊!!!
3 回答
收到一只叮咚
TA贡献1821条经验 获得超4个赞
这个和laravel没有关系。
数据库里的phone字段是varchar型,但是你查询的数据是int型,这里导致了mysql隐式类型转换,所以你的索引失效。
在设计表的时候就需要考虑好这些问题,实现的过程做好类型约束
手掌心
TA贡献1942条经验 获得超3个赞
对!这就是程序员要处理的事情。
这种用法是PDO的方式,与laravel无关。
mysql的类型是开发者定义的,所以该使用什么类型,也由开发者决定
这是不是框架层和语言层要解决的事情,即使裸写sql,一样会有人写错。
换个角度,这其实是sql的使用知识,只不过通过中间层控制sql,有不同的使用规则,这是需要使用者掌握的
- 3 回答
- 0 关注
- 396 浏览
添加回答
举报
0/150
提交
取消