试图参数化SELECT查询

时间:2014-12-13 09:10:15

标签: php sql mysqli parameterized-query

基本上,我希望我的代码可以安全地从SQL注入。我在网上读到mysqli_real_escape_string对SQL注入是不安全的,并且读取参数化是要走的路。因此,从下面的代码中,我可以将帐户添加到数据库中,但我无法检查该帐户是否已存在。

<?php
require 'privstuff/dbinfo.php';

$firstname = $_POST["firstname"];
$password1 = $_POST["password1"];
$email = $_POST["email"];
$ip = $_SERVER['REMOTE_ADDR'];
$username = $_POST["username"];

$mysqli = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_DATABASE);


if(mysqli_connect_errno()) {
    echo "Connection Failed. Please send an email to owner@othertxt.com regarding this problem.";
    exit();
}


//$username = mysqli_real_escape_string($mysqli,$_POST['username']);     
//$result = mysqli_query($mysqli,"SELECT `username` FROM `accounts` WHERE username = '$username'");  



if ($stmt = $mysqli->prepare("SELECT `username` FROM `accounts` WHERE username = ?")) {


    $stmt -> bind_param("s", $username);

    $stmt -> execute();

    $stmt -> bind_result($result);

    $stmt -> fetch();

    $stmt -> close();
}

if(mysqli_num_rows($result)>0){  

    header('Location: /register.html');
}else{  
    if ($stmt = $mysqli->prepare("INSERT INTO `accounts`(`firstname`, `username`, `password`, `email`, `ip`) VALUES (?,?,?,?,?)")) {


        $stmt -> bind_param("sssss", $firstname, $username,  password_hash($password1, PASSWORD_BCRYPT), $email, $ip);

        $stmt -> execute();

        $stmt -> bind_result($result);

        $stmt -> fetch();

        $stmt -> close();
    }


    $mysqli->close(); 
    header('Location: /login.html');   
}

?>

由于问题已暂停,我无法添加自己的答案。 Reddit上有人给出了这个问题的精彩解释。 Here it is

2 个答案:

答案 0 :(得分:1)

参数化的一个好处是,您不再需要直接关注各种数据类型的handling of quotes - 这些将由bind处理:

$mysqli->prepare("SELECT `username` FROM `accounts` WHERE username = ?" ...

答案 1 :(得分:1)

除了@Stuart的上述答案(涵盖预备语句中的引号)之外,您在错误的地方引用了num_rows

$stmt -> bind_result($result);
if(mysqli_num_rows($result)>0){ 

您应该将它引用到语句对象:

if($stmt->num_rows > 0) {
    // do whats necessary       
}

在插入后获取行没有意义,你实际上并不需要那些。

以下是它的汇编:

<?php
require 'privstuff/dbinfo.php';

$firstname = $_POST["firstname"];
$password1 = $_POST["password1"];
$email = $_POST["email"];
$ip = $_SERVER['REMOTE_ADDR'];
$username = $_POST["username"];

$mysqli = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_DATABASE);
if(mysqli_connect_errno()) {
    echo "Connection Failed. Please send an email to owner@othertxt.com regarding this problem.";
    exit;
}

if ($stmt = $mysqli->prepare("SELECT `username` FROM `accounts` WHERE username = ?")) {
    $stmt->bind_param("s", $username);
    $stmt->execute();
}

if($stmt->num_rows > 0) {  
    header('Location: /register.html');
} else {  
    if ($stmt = $mysqli->prepare("INSERT INTO `accounts`(`firstname`, `username`, `password`, `email`, `ip`) VALUES (?,?,?,?,?)")) {

        $stmt->bind_param("sssss", $firstname, $username,  password_hash($password1, PASSWORD_BCRYPT), $email, $ip);
        if($stmt->execute()) {
            header('Location: /login.html');
            $stmt->close();
        } else {
            die($mysqli->error);
        }     
    }
}