PHP PDO操作SQLite判断用户是否存在始终返回存在的问题求解
问题根源
你的代码有3处核心错误,直接导致判断逻辑永远失效:
- PDO错误属性配置错误:你写的
PDO::AFTER_ERRMODE是不存在的常量,正确配置名应为PDO::ATTR_ERRMODE。这行配置失效时,PDO会默认静默忽略SQL错误,你根本无法感知语句执行是否正常。 - 结果集判断逻辑完全错误:
SELECT EXISTS(...)语句的执行逻辑是无论是否匹配到记录,都会固定返回1行结果:匹配成功时该行的字段值为1,匹配失败时值为0。你用count($result) > 0判断结果集行数,无论哪种情况结果集都有1行,自然永远输出exists。 - 密码校验逻辑错误:
password_hash()每次调用都会生成带随机盐的新哈希值,你把用户输入的密码当场哈希后直接和数据库里存储的哈希做SQL匹配,哪怕明文密码正确,两个哈希值也不可能相等,这种写法永远无法正确校验密码。
修正后的实现
$db = new PDO('sqlite:practice.sqlite'); // 修正PDO错误模式属性名 $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $name = ''; if(isset($_POST['name'])) { $name = $_POST['name']; } $password = ''; if(isset($_POST['password'])) { $password = $_POST['password']; } // 第一步:只按用户名查询对应用户记录,不要在SQL中匹配密码哈希 $query = $db->prepare("SELECT * FROM users WHERE name = :name"); $query->execute(array(':name' => $name)); $user = $query->fetch(PDO::FETCH_ASSOC); // 第二步:先判断用户是否存在,再用password_verify校验密码 if($user && password_verify($password, $user['password'])) { echo 'exists'; } else { echo 'doesnt exist'; }
如果你坚持要用聚合查询做存在性判断,直接取返回的计数值即可,不要判断结果集行数:
$query = $db->prepare("SELECT COUNT(*) FROM users WHERE name = :name"); $query->execute(array(':name' => $name)); // 直接取第一列的计数值,大于0说明存在对应用户 $userExists = $query->fetchColumn() > 0;
注意:永远不要把
password_hash()的结果放在SQL条件里做等值匹配,校验密码必须使用PHP原生的password_verify()函数。
内容的提问来源于stack exchange,提问作者a.anev
相关产品推荐
相关产品推荐

