2013-11-22 22 views
-1

我是SQL查询的新手,我一直在根据网站上提供的信息以及本网站本身的信息进行学习,这些信息从2005年至今年发布的信息有所不同。我正在创建一个将数据插入MySql数据库的php应用程序。当我在研究有关Sql注入的时候,网络上有很多信息。我阅读了各种方法来实现它,比如使用mysql_real_escape_string,使用sqli或PDO编写语句和参数化查询等。我将所学到的东西放在一起,并使用sqli方法进行准备和参数化查询。在我将它发布到我的网站上之前,我只想确保我已经正确完成了这项工作,并且这应该防止SQL注入。我对此感到非常紧张,如果有人能让我知道,如果以下问题对我来说是安全的,那么这将非常有帮助。我对这个新手,只需要重新保证:担心SQL注入。我的代码是否正确?

我现在下面的代码:

//Connect to Database 

$user_input_Name = $_POST['Name']; 
$user_input_date = $_POST['date']; 
$user_input_info = $_POST['info']; 
$user_input_resume = $_POST['resume']; 
$user_input_experience = $_POST['experience']; 
$user_input_dateGraduated = $_POST['dateGraduated']; 

//Preparing the query 
$stmt = $mysqli->prepare("INSERT INTO our_weekend_template (name, date, info, resume, experience, date_graduated) VALUES (?, ?, ?, ?, ?, ?)"); 

// Check that $stmt creation succeeded 
// prepare() can fail because of syntax errors, missing privileges, .... 
if (false===$stmt) { 
    // and since all the following operations need a valid/ready statement object 
    // it doesn't make sense to go on 
    // you might want to use a more sophisticated mechanism than die() 
    // but's it's only an example 
    die('prepare() failed: ' . htmlspecialchars($mysqli->error)); 
} 

// "s" means the database expects a string 
$rc = $stmt->bind_param("ssssss", $user_input_Name, $user_input_date, $user_input_info, $user_input_resume, $user_input_experience, $user_input_dateGraduated); 

// bind_param() can fail because the number of parameter doesn't match the placeholders in the statement 
// or there's a type conflict(?), or .... 
if (false===$rc) { 
    // again execute() is useless if you can't bind the parameters. Bail out somehow. 
    die('bind_param() failed: ' . htmlspecialchars($stmt->error)); 
} 

$stmt->execute(); 

// execute() can fail for various reasons. And may it be as stupid as someone tripping over the network cable 
// 2006 "server gone away" is always an option 
if (false===$rc) { 
    die('execute() failed: ' . htmlspecialchars($stmt->error)); 
} 

$stmt->close(); 


//Disconnect from database 

我在做什么这里是我使用的准备,bind_param和执行来处理查询然后为它的每一步添加一个错误,所以如果它失败了,所以它对调试很有用。

这些都是我提到把上面的代码一起页:

How can I prevent SQL injection in PHP?

MySQLi prepared statements error reporting

http://www.wikihow.com/Prevent-SQL-Injection-in-PHP

是不是很好,而且是安全的,让我有代码因为它在我的现场?我错过了什么吗?我需要改进什么以提高安全性吗?

+0

我认为Code Reviews不应该在SO上转到codereview.stackexchange.com。但一眼看不出你的问题。 – Amber

+4

可能更适合codereview.stackexchange.com – Mureinik

+0

感谢您的意见。我没有意识到codereview.stackexchange.com。我一定会在将来使用它。干杯! – Neel

回答

1

准备好的语句把SQL注入锁定了,所以是的,你做得对!你的错误处理是太优秀:)

稍微offtopic:

在PHP中,你不必值比较明确为false。 if语句中的所有内容都会自动分析为布尔值。所以非空对象返回true,而false则返回false。

if(!$stmt) die(); 

但是,你的代码绝对没有错。

+0

非常感谢Tim。所有人的再保证让我放心。过去几天我阅读材料时,我非常担心。通过错误处理,我确实从VolkerK提出的另一个话题中得到了启发,我喜欢这种方法。我一定会接受你对php的意见,这很有道理。我将用它编辑我的代码,它也简化了它。再次感谢蒂姆。多谢!:) – Neel

+2

@TimS一些mysqli函数(也可以是PDO)可以返回'0'或'NULL',这将评估为'false'。对于这些与“false”的显式比较是区分“错误”和“什么都没有发生”的唯一方法。我会离开测试,因为它们是完全清楚发生了什么事情。 – 2013-11-22 13:17:29

+0

@MikeW True,但'mysqli :: prepare()'返回一个对象或false,'mysqli_stmt :: bind_param'返回true或false,'mysqli_stmt :: execute'返回true或false。所以在这种情况下,它会很好。但是,是的,你还是对的,它应该**被提及:) –