我正在尝试使用SQlite创建登录页面。但是,出于某种原因,我一直在收到错误( 致命错误:未捕获错误:在C:\ xampp \ htdocs \ project \ login.php中调用boolean上的成员函数fetch():20堆栈跟踪:#0 {main}抛出C:\ xampp \ htdocs \ project \第20行的login.php)
<?php
include("config.php");
session_start();
$error = "";
if(@$_SESSION['login_user'] != null){
header("location: dashboard.php");
}
if(!empty($_POST['username']) && !empty($_POST['password'])) {
// username and password sent from form
$myusername = strtolower($_POST['username']);
$mypassword = $_POST['password'];
$dir = 'sqlite:db.sqlite3';
$dbh = new PDO($dir) or die("cannot open the database");
$sql = "SELECT username, password FROM users_ WHERE username = '$myusername' and password = '$mypassword'";
$result = $dbh->query($sql);
$row = $result->fetch();
echo $row['username'];
echo $row['password'];
}
?>
答案 0 :(得分:1)
从PHP doc:PDO :: query()返回PDOStatement对象,失败时返回FALSE。这意味着如果执行SQL查询出错,$dbh->query($sql)
可以返回布尔值(false)(您应该添加代码来处理这种可能性)。您收到的错误消息强烈建议就是这种情况。
所以,让我们看看,导致SQL失败的原因可能是什么。这些都是可能的......
$password
的值包含一个字符,如'
(单引号),会导致错误的SQL语句。UPDATE(回答下面的评论):您正在构建整个SQL语句,包括PHP中的所有数据值,作为字符串,然后PDO才能看到它。所以PDO只看到字符串,所以它不能知道或处理应该转义的特殊字符。 PDO必须非常聪明才能知道哪些字符是可以的,哪些不是(特别是如果数据是SQL注入;如果PDO解析它寻找要逃脱的字符,它看起来会很好。)
实际上,您的代码会暴露给SQL注入。你应该1)逃避数据......
$sql = "SELECT username, password FROM users_ WHERE "
. "username = '" . $dbh->quote($myusername) . "' "
. "and password = '" . $dbh->quote($mypassword) . "'";
或(更好!)2)使用预准备语句(PDO将执行任何必要的转义,因为它替换SQL语句中?
的数据值)
$sql = "SELECT username, password FROM users_ WHERE "
. "username = ? AND password = ?"; // note the "?" placeholders
$stmt = $dbh->prepare($sql);
$stmt->execute([$myusername, $mypassword]); // here, PDO will escape characters
while ($row = $stmt->fetch()) {
// process a $row
}