PHP登录注册系统中real_escape_string()成员函数调用错误排查
修复PHP登录/注册系统中的“调用成员函数real_escape_string()”错误及密码验证问题
我用PHP开发了一套登录/注册系统,现在遇到两个问题:一是登录时出现“调用成员函数real_escape_string()”的错误,不知道怎么修;二是需要验证用户在signup.php输入的密码和signup_user.php中哈希后的密码是否一致。
一、修复“调用成员函数real_escape_string()”错误
错误原因
signin.php中你用$mysqli = require __DIR__ . "/connection.php";获取连接,但connection.php创建的是过程式mysqli连接(变量$con),require执行成功返回的是1而非mysqli对象,因此调用$mysqli->real_escape_string()时会报错——1不是对象,没有该成员方法。
修复方案
方式1:改用过程式函数mysqli_real_escape_string
修改signin.php的SQL拼接逻辑,直接使用过程式函数并传入正确的连接变量:
<?php ini_set("display_errors", "1"); ini_set("display_startup_errors", "1"); error_reporting(E_ALL); $is_invalid = false; if ($_SERVER["REQUEST_METHOD"] === "POST") { // 先引入连接文件,获取过程式连接变量$con require __DIR__ . "/connection.php"; // 改用过程式转义函数 $sql = sprintf("SELECT * FROM users WHERE user_name = '%s'", mysqli_real_escape_string($con, $_POST["Username"])); $result = mysqli_query($con, $sql); $user = mysqli_fetch_assoc($result); if ($user) { // 注意:此处字段名要和数据库存储的一致,后续会说明 if (password_verify($_POST["Password"], $user["user_pass"])) { session_start(); session_regenerate_id(); $_SESSION["id"] = $user["user_id"]; echo "Successful Login :) ... redirecting"; exit; } } $is_invalid = true; } ?>
方式2:将connection.php改为面向对象连接
修改connection.php,返回mysqli对象:
<?php $mysqli = new mysqli("localhost", "root", "", "ecom"); if ($mysqli->connect_error) { die("Connection was not established: " . $mysqli->connect_error); } ?>
此时signin.php的原代码即可正常运行,因为$mysqli会被赋值为有效的mysqli对象。
二、修复密码验证不匹配问题
问题根源
- 登录时你尝试读取
$user["password_hash"],但注册时哈希后的密码存在了user_pass字段中,字段名不匹配; - 注册时不必要地存储了
confirm_password_hash和confirm_user_pin,既浪费存储空间,也不符合逻辑(只需验证原输入一致,无需存储哈希后的确认值)。
修复步骤
1. 优化signup_user.php的密码存储逻辑
<?php ini_set("display_errors", "1"); ini_set("display_startup_errors", "1"); error_reporting(E_ALL); include("/Applications/XAMPP/xamppfiles/htdocs/Ecom/chat/code/connection.php"); if(isset($_POST['sign_up'])){ $password = $_POST['user_pass']; $confirm_password = $_POST['confirm_user_pass']; $pin = $_POST['user_pin']; $confirm_pin = $_POST['confirm_user_pin']; // 仅哈希需要存储的密码和PIN,确认值无需哈希 $password_hash = password_hash($password, PASSWORD_DEFAULT); $pin_hash = password_hash($pin, PASSWORD_DEFAULT); $name = htmlentities(mysqli_real_escape_string($con,$_POST['user_name'])); $pass = htmlentities(mysqli_real_escape_string($con,$password_hash)); $pin = htmlentities(mysqli_real_escape_string($con,$pin_hash)); // 保留原有的验证逻辑... // 检查用户名重复逻辑... // 修改插入SQL,移除不必要的确认字段 $insert = "insert into users (user_name, user_pass, user_pin) values ('$name', '$pass', '$pin')"; $query = mysqli_query($con,$insert); // 保留原有的注册结果提示逻辑... } ?>
2. 对齐登录时的字段读取
确保signin.php中读取的密码字段和数据库存储的一致:
// 数据库存储的密码字段是user_pass,因此此处要对应 if (password_verify($_POST["Password"], $user["user_pass"])) { // 登录成功逻辑 }
额外建议:使用预处理语句防SQL注入
手动转义存在风险,推荐使用mysqli预处理语句替代字符串拼接,以彻底避免SQL注入:
// 以面向对象为例,signin.php的查询逻辑可改为: $stmt = $mysqli->prepare("SELECT * FROM users WHERE user_name = ?"); $stmt->bind_param("s", $_POST["Username"]); // "s"表示字符串类型参数 $stmt->execute(); $result = $stmt->get_result(); $user = $result->fetch_assoc();
内容的提问来源于stack exchange,提问作者Thomas Eddington III
相关产品推荐
相关产品推荐

