You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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对象。

二、修复密码验证不匹配问题

问题根源

  1. 登录时你尝试读取$user["password_hash"],但注册时哈希后的密码存在了user_pass字段中,字段名不匹配;
  2. 注册时不必要地存储了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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 17:17:03