典型的手机号问题,数据库varchar, 手机号加了索引,但是php传参传int
public 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, 扣绩效?批评?
红颜莎娜
收到一只叮咚
手掌心