2014-12-13 7 views
1

В принципе, я хочу, чтобы мой код был в безопасности от SQL Injection. Я читал онлайн, что mysqli_real_escape_string небезопасен для SQL-инъекций и читает, что параметризация - это путь. Поэтому из приведенного ниже кода я могу добавлять учетные записи в базу данных, но я не могу проверить, существует ли учетная запись.Попытка параметризовать запрос SELECT

<?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 [email protected] 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

ответ

1

Одним из преимуществ параметрирования является то, что вам больше не нужно непосредственно касаться себя с handling of quotes для различных типов данных - они будут обработаны безвыходным:

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

В дополнении к @ Стюарту ответ выше, который охватывает цитаты в подготовленном заявлении, вы ссылаетесь на 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 [email protected] 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); 
     }  
    } 
} 
+0

Что вы говорите, имеет смысл. Но я немного смущен тем, где положить остальную часть моей, которая уже находится внутри 'if ($ stmt-> num_rows> 0)' – DanMossa

+0

@ Dgameman1 i пересмотрены некоторые части, надеюсь, это пролить немного света. – Ghost

+0

. страницу входа, но он не добавляет их в базу данных. Даже если пользователь существует или нет. – DanMossa