2011-07-15 26 views
0

我可以使用上如何與關係數據庫預處理語句

$query = mysql_query("SELECT M.msg_id, M.uid_fk, M.message, M.created, U.username FROM messages M, users U WHERE M.uid_fk=U.uid and M.uid_fk='$uid' order by M.msg_id desc ") 

改變這種查詢到一份聲明中提供一些幫助。我不確定mysqli_stmt_bind_param()會發生什麼。 這是我到目前爲止有:

$stmt = mysqli_prepare($link, "SELECT M.msg_id, M.uid_fk, M.message, M.created, U.username FROM messages M, users U WHERE M.uid_fk=? and M.uid_fk=? order by M.msg_id desc")) { 


mysqli_stmt_bind_param($stmt, "s,s", $uid,$uid); 

我知道$ UID,$ uid是不正確的,關於如何更改M.uid_fk = U.uid和M.uid_fk ='$ UID工作在bind_para中。

感謝

+0

正如所寫的,如果用戶可以控制'$ uid'中的內容,那麼您的代碼容易受到SQL注入的影響。使用佔位符準備好的語句的一個主要優點是您不再受SQL注入的影響 - 除非您執行的是一個執行動態SQL並且不使用佔位符的存儲過程。 –

回答

2

你只需要綁定你真正打算通過在使您的查詢保持幾乎相同的:

$stmt = mysqli_prepare("SELECT M.msg_id, M.uid_fk, M.message, M.created, U.username FROM messages M, users U WHERE M.uid_fk=U.uid and M.uid_fk= ? order by M.msg_id desc"); 

mysqli_stmt_bind_param($stmt, "s", $uid); 

也不當你有多個PARAMS綁定類型不是逗號如果它看起來像這樣:

mysqli_stmt_bind_param($stmt, "sss", $uid, $someString, $someOtherString); 

最後如果你真的應該使用PDO。 Mysqli很難合作,特別是在準備好的陳述中。例如,這是從php.net手冊準備好的聲明例如:

$mysqli = new mysqli("localhost", "my_user", "my_password", "world"); 

/* check connection */ 
if (mysqli_connect_errno()) { 
    printf("Connect failed: %s\n", mysqli_connect_error()); 
    exit(); 
} 

$query = "SELECT Name, CountryCode FROM City WHERE CountryCode = ? ORDER by ID DESC LIMIT 150,5"; 

// you can only bind by reference so we have to do this... and it gets really annoying! 
$code = 'US'; 

if ($stmt = $mysqli->prepare($query)) { 

    $stmt->bind_param($stmt, 's', $code); 

    /* execute statement */ 
    $stmt->execute(); 

    /* bind result variables - we have to do this as well with is really annoying! */ 
    $stmt->bind_result($name, $code); 

    /* fetch values */ 
    while ($stmt->fetch()) { 
     printf ("%s (%s)\n", $name, $code); 
    } 

    /* close statement */ 
    $stmt->close(); 
} 

而且做同樣與PDO:

try { 

    $pdo = new PDO("mysql:host=localhost;dbname=mydb", "my_user", "my_password"); 
} catch(PDOException $e) { 
    printf("Connect failed: %s\n", $e->getCode()); 
    exit(); 
} 

$query = "SELECT Name, CountryCode FROM City WHERE CountryCode = ? ORDER by ID DESC LIMIT 150,5"; 

    // when you call prepare you can bind all the vairables immediately 
    // or you can do it ehn you call PDOStatement::execute() 

    if ($stmt = $pdo->prepare($query, array('US')) { 


     /* execute statement */ 
     // if we wanted to bind params at execution time we could use 
     // $pdo->execute(array('US')); 
     $stmt->execute(); 


     /* fetch values */ 
     while (false !== ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { 
      printf ("%s (%s)\n", $row['Name'], $row['Code']); 
     } 

     /* close statement */ 
     $stmt->close(); 
    } 

現在,如果你想綁定到引用變量的結果或參數,仍然可以通過PDO來做到這一點,但是我發現這樣做更容易,更靈活。所以真的是關於靈活性。您可以使用簡單的過程來實現簡單的事情,或者在需要時使用更復雜的過程。