2011-04-04 109 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(); 
}