2011-04-04 115 views
3

我想了解更多关于MySQL和如何防止SQL注入,所以我的研究已经带给我准备好的语句,似乎是要走的路。如何使用MySQLi准备好的语句和存储过程

我还在学习如何编写存储过程,现在正试图将两者结合起来。虽然没有太多的信息。

在我的PHP测试应用程序的那一刻我有一个调用一个正常的MySQL命令像这样的SP功能:

mysql_query("CALL usp_inserturl('$longurl', '$short_url', '$source')");

我怎样才能做的MySQLi和准备语句相同尽可能安全地注射?

谢谢!

+0

为什么没有人似乎直接用代码示例回答了这个问题? – 2015-01-18 13:49:14

回答

2

您可能会发现使用如下回答:

MySql: Will using Prepared statements to call a stored procedure be any faster with .NET/Connector?

另外:

授予执行权限,只有这样您的应用程序级用户( s)只能调用存储过程。这样一来,你的应用程序的用户(一个或多个)只能与数据库通过存储过程API进行交互,它们直接不能:

select, insert, delete, update, truncate, drop, describe, show etc. 

没有比这更安全。唯一的例外是,如果您在您的存储过程中使用了动态sql,那么我会不惜一切代价避免 - 至少在您意识到危险的情况下才会这样做。

当构建数据库时,例如foo_db,我通常创建两个用户。第一个foo_dbo(数据库所有者)是拥有该数据库并被授予完全权限(ALL)的用户,因此他们可以创建模式对象并根据需要操作数据。第二个用户foo_usr(应用程序用户)只被授予执行permisisons,并在我的应用程序代码中用于通过我创建的存储过程API访问数据库。

希望这有助于:)

4

尝试以下操作:

$mysqli= new mysqli(... info ...); 
$query= "call YourSPWithParams(?,?,?)"; 
$stmt = $mysqli->prepare($query); 
$x = 1; $y = 10; $z = 14; 
$stmt->bind_param("iii", $x, $y, $z); 
$stmt->execute(); 
+0

酷!几乎与任何其他'SELECT'语句相似;唯一的区别是你必须用'CALL'启动SQL。 – 2011-04-04 11:16:53

+0

你可以添加如何从'$ stmt'检索结果的代码吗? – Gruber 2013-05-23 11:44:18

+2

@Gruber你可以在这里找到一个如何检索Example#5中的数据的例子:http://php.net/manual/en/mysqli.quickstart.stored-procedures.php – Jimmy 2013-06-11 16:16:21

0

您可以同时使用:

grant all on foo_db.* to [email protected] identified by 'pass'; 

grant execute on foo_db.* to [email protected] identified by 'pass'; 

最后你可以通过使用mysql_real_escape_string提高你上面的代码示例他们在同时:只需使用存储过程进行准备:

//prepare and bind SP's parameters with your variables only once 
$stmt=$db->prepare("CALL MyStoredProc(?,?)"); 
$stmt->bind_param('is',$i,$name); 

//then change binded variables and execute statement multiple times 
for($i=1;$i<9;$i++) 
{ 
    $name="Name".$i; 
    $stmt->execute(); 
}