PHP登录表单返回错误 [英] PHP login form returning error

查看:72
本文介绍了PHP登录表单返回错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在下面创建了一个登录脚本,但是被告知要使用准备好的语句

I have created a login script below, however I have been told to use prepared statements

<?php
require '../php/connect.php';
if(isset($_POST['login'])){
    $username = mysqli_real_escape_string($con, $_POST['username']);
    $password = mysqli_real_escape_string($con, $_POST['password']);    
    $select_user = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
    $run_user = mysqli_query($con, $select_user);
    $check_user = mysqli_num_rows($run_user);
    if($check_user>0){
        header('location:../dashboard.php');
    }else{
        header('location:/pages/loginerror.php');
    }
}
?>

出于安全原因了解了准备好的语句后,我开始阅读准备好的语句,但是我似乎无法使其在下面正常工作.我得到的错误是解析错误:语法错误,/usr/local/www/apache24/data/timed/php/login.php在第9行出现意外的'mysqli_stmt_bind_param'(T_STRING)"

After learning about prepared statements for security reasons i started reading prepared statements however i just do not seem to be able to get it to work below. the error i get is "Parse error: syntax error, unexpected 'mysqli_stmt_bind_param' (T_STRING) in /usr/local/www/apache24/data/timed/php/login.php on line 9"

<?php

require '../php/connect.php';
if(isset($_POST['login'])){
    $username = mysqli_real_escape_string($con, $_POST['username']);
    $password = mysqli_real_escape_string($con, $_POST['password']);

    $stmt = mysqli_prepare($con, "SELECT * FROM users WHERE username = ? AND password = ?")
    $stmt->mysqli_stmt_bind_param($stmt, "ss", '$username', '$password');
    mysqli_stmt_execute($stmt);

    $run_user = mysqli_query($con, $stmt);
    $check_user = mysqli_num_rows($run_user);


    if($check_user>0){
        header('location:../dashboard.php');
    }else{
        header('location:/pages/loginerror.php');
    }
}
?>

推荐答案

由于您正在学习,所以不仅要告诉您您做错了什么,我还要添加一些有关为什么的解释错误:

Since you're learning, instead of just telling you what you're doing wrong I'll add some explanations about why it's wrong:

$username = mysqli_real_escape_string($con, $_POST['username']);
$password = mysqli_real_escape_string($con, $_POST['password']);

如果使用准备好的语句,则不得使用_escape_string()函数.在准备好的语句中,您将参数绑定为特定类型(字符串,整数等).如果您绑定的变量已通过_escape_string()函数传递,则PHP冒用双换义某些字符并破坏值的风险.你不要那个.

If you're using prepared statements, you must not use the _escape_string() functions. In a prepared statement you bind your parameters as a particular type (string, integer, etc.). If the variables you bind have been passed through the _escape_string() functions you risk PHP double-escaping certain characters and corrupting your values. You don't want that.

$stmt = mysqli_prepare($con, "SELECT * FROM users WHERE username = ? AND password = ?")

此行末尾缺少;.

$stmt->mysqli_stmt_bind_param($stmt, "ss", '$username', '$password');

这里有两个问题:

您传递的是字符串 '$username''$password',而不是传递实际的变量$username$password.这意味着您的数据库将按字面意义查找"$username""$password"而不是这些变量的内容.您需要删除引号.

Instead of passing the actual variables $username and $password, you're passing the string '$username' and '$password'. That means that your database will look for literally "$username" and "$password" instead of whatever the content of those variables is. You need to lose the quotation marks.

第二个(也是更重要的)问题是您在这里混合了过程式和面向对象的样式.您可以通过两种方式调用bind_param函数:

The second (and more important) problem is that you're mixing procedural and object-oriented styles here. You can call the bind_param function in two ways:

mysqli_stmt_bind_param($stmt, "ss", $username, $password);
// or:
$stmt->bind_param("ss", $username, $password);

您需要选择以下方式之一.就他们所做的事情而言,这确实没有什么区别.这只是个人喜好问题,结果是完全一样的.如果使用第一个选项,则需要告诉函数要将变量绑定到哪个准备好的语句,使用第二个选项,您已经在语句本身上调用了该函数,因此无需添加该参数.

You need to choose one of these ways. In terms of what they do it really makes no difference. It's just a matter of personal preference, the outcome is exactly the same. If you're using the first option you need to tell the function which prepared statement you want to bind the variables to, using the second option you're already calling the function on the statement itself, so there's no need to add that argument.

mysqli_stmt_execute($stmt);

好.

$run_user = mysqli_query($con, $stmt);

不好.

mysqli_query().您不能将其与准备好的语句一起使用. mysqli_stmt_excute()已经在您的数据库上执行了查询.您需要将此呼叫删除到mysqli_query().

mysqli_query() is used when you want to perform a literal SQL query. You cannot use that with a prepared statement. mysqli_stmt_excute() has already executed the query on your database. You need to remove this call to mysqli_query().

请记住,执行准备好的语句可能会失败.如果由于某种原因,您的准备好的语句无法执行(例如您的SQL查询中有错字,数据库连接已断开,等等),mysqli_stmt_execute()将返回false.进行检查始终是明智的做法,以使调试工作变得非常容易.

Keep in mind that executing your prepared statement can fail. If, for some reason, your prepared statement fails to execute (maybe there's a typo in your SQL query, the database connection has dropped, etc.) mysqli_stmt_execute() will return false. It is always wise to check for this, to make debugging things a heck of a lot easier.

$check_user = mysqli_num_rows($run_user);

这几乎是正确的,除了您需要从语句本身检索行数,因为这是查询与数据库的交互. 您需要调用mysqli_num_rows($stmt). 编辑:正如您正确指出的那样,mysqli_num_rows()不适用于语句.您需要改用mysqli_stmt_num_rows($stmt).

This is almost correct, except that you need to retrieve the number of rows from the statement itself, since that is your query's interaction with the database. You need to call mysqli_num_rows($stmt) instead. Edit: As you rightly pointed out, mysqli_num_rows() doesn't work on statements. You need to use mysqli_stmt_num_rows($stmt) instead.

如果您一直在输入,则应该以类似以下内容结束

If you've been typing along, you should have ended up with something similar to:

<?php

require '../php/connect.php';
if(isset($_POST['login'])){
    $username = $_POST['username'];
    $password = $_POST['password'];

    $stmt = mysqli_prepare($con, "SELECT * FROM users WHERE username = ? AND password = ?");
    mysqli_stmt_bind_param($stmt, "ss", $username, $password);
    $success = mysqli_stmt_execute($stmt);

    if (!$success) {
        echo "Query failed: " . mysqli_stmt_error($stmt);
        die();
    }

    $check_user = mysqli_stmt_num_rows($stmt);

    if($check_user>0){
        header('location:../dashboard.php');
    }else{
        header('location:/pages/loginerror.php');
    }
}
?>

这篇关于PHP登录表单返回错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆