PHP 准备好的声明与 mysqli_real_escape_string

PHP Prepared Statement vs mysqli_real_escape_string

我在下面写了一些代码。我想知道两件事。

1.我的代码有漏洞吗?

2。我需要将 mysqli_real_escape_string 与准备好的语句一起使用吗?它会作为额外的安全层还是多余的?

使用的代码:

if ($_SERVER['REQUEST_METHOD'] == 'POST') 
{
$admin_type = mysqli_real_escape_string($conn, $_POST['admin_type']);
$position = mysqli_real_escape_string($conn, $_POST['position']);
$first_name = mysqli_real_escape_string($conn, $_POST['first_name']);
$last_name = mysqli_real_escape_string($conn, $_POST['last_name']);
$user_name = mysqli_real_escape_string($conn, $_POST['user_name']);
$email = mysqli_real_escape_string($conn, $_POST['email']);
$phone_number = mysqli_real_escape_string($conn, $_POST['phone_number']);
$passwd = mysqli_real_escape_string($conn, $_POST['passwd']);
$created_at = mysqli_real_escape_string($conn, $_POST['created_at']);
$about = mysqli_real_escape_string($conn, $_POST['about']);

$sql = "INSERT INTO admin_accounts (admin_type, position, first_name, last_name, user_name, email, phone_number, passwd, about) VALUES (?,?,?,?,?,?,?,?,?);";

$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
    echo "SQL Error";
} else {
    mysqli_stmt_bind_param($stmt, "sssssssss", $admin_type, $position, $first_name, $last_name, $user_name, $email, $phone_number, $passwd, $about);
    mysqli_stmt_execute($stmt);
  {
     $_SESSION['success'] = "Admin user added successfully!";
     header('location: admin_users');
     exit();
    }     
}
    
}

转义对于使用查询参数来说是多余的。如果您还使用绑定查询参数,请不要使用转义。您最终会在数据库中得到包含文字反斜杠的数据。

只需使用查询参数。绑定参数比对 mysqli_real_escape_string().

的所有调用更容易和更简单

使用 PDO 更容易,因为您甚至不需要进行绑定。

示例:

if ($_SERVER['REQUEST_METHOD'] == 'POST')
{   
    $param_keys = ['admin_type'=>null, 'position'=>null, 'first_name'=>null, 
        'last_name'=>null, 'user_name'=>null, 'email'=>null, 'phone_number'=>null, 
        'passwd'=>null, 'created_at'=>null, 'about'=>null];

    // make sure the params include all keys in $param_keys,
    // but no keys that aren't in $param_keys
    $params = array_merge($param_keys, array_intersect_key($_POST, $param_keys));

    $sql = "
        INSERT INTO admin_accounts 
        SET admin_type = :admin_type,
            position = :position,
            first_name = :first_name,
            last_name = :last_name,
            user_name = :user_name,
            email = :email,
            phone_number = :phone_number,
            passwd = :passwd,
            about = :about";

    $stmt = $pdoConn->prepare($sql);
    $stmt->execute($params);
    $_SESSION['success'] = "Admin user added successfully!";
    header('location: admin_users');
}   

我假设你 configured PDO to throw exceptions on error

一个古老的论点 PHP Prepared Statement 和 PHP mysqli_real_escape_string 不执行相同的功能,尽管两者都有相同的目标,即尝试获取您的字符串或用户输入may 不会对您的数据库造成伤害的格式 我使用术语 may 因为缺乏适当的验证仍然会导致同样的问题。

例如,用户删除自己的 post 未经适当验证的删除查询,用户可能会删除其他用户的 post,用户甚至不需要 SQL 注入存档。

string mysqli_real_escape_string ( mysqli $link , string $escapestr )

此函数用于创建可在 SQL 语句中使用的合法 SQL 字符串。给定的字符串被编码为转义的 SQL 字符串,考虑到 current character set of the connection 现在这意味着 mysqli_real_escape_string 取决于您当前的字符集。

虽然准备好的语句将您的值/用户输入绑定到特定的 Data type 并指示您的 sql 这样对待它,但这也取决于您指定的数据类型。

基本上 mysqli_real_escape_string 会根据定义的字符集去除用户输入中的垃圾,而准备好的语句将确保用户输入中是否有任何垃圾,它只会按照您想要的方式进行解释被解释为通常是用户垃圾 :)

我想说的是,同时使用这两者并不是一个坏主意,但保护您的数据库的责任落在您身上,开发人员需要采取所有必要且合乎逻辑的步骤来实现最大安全性,没有人关心被黑网站的速度有多快! !