2017-02-09 107 views
1

我對PDO相當陌生,正試圖將我的MySQLi程序結構化的PHP代碼更改爲面向對象的PDO結構。我正在學習準備,執行,bindParam/bindValue等等,以達到一定程度的成功。PDO使用子查詢準備

我的問題是,當用戶提交的值在查詢的子查詢中時,我該如何準備查詢?

我有一個變量用作php中的子查詢(其中$ playerOne,$ playerTwo是用戶提交的值)。

$sqlPlayerOne = "(SELECT * FROM players WHERE Player_name = $playerOne)"; 
$sqlPlayerTwo = "(SELECT * FROM players WHERE Player_name = $playerTwo)"; 

這是爲了得到這些球員的所有記錄。舉個例子,我可以比較一下他們比賽的比賽,例如

$sqlWith = "SELECT * FROM $sqlPlayerOne s1 
WHERE EXISTS (SELECT * FROM $sqlPlayerTwo s2 WHERE s1.Team_name = s2.Opposing_team) 

注意:SELECT *只是用來使它在這裏更具可讀性。

是否足夠做$pdoWith = $db->prepare($sqlWith)或我應該先準備$sqlPlayerOne首先,因爲這有用戶提交的價值?

我意識到我可以在每個需要它的主查詢中複製/粘貼子查詢,但是如果我不需要,我寧願不要。

編輯:抱歉,缺乏清晰度。這是我改變之前我的代碼的一部分,因爲我不知道如何改變它。看來我將不得不做類似@JC森林如何指出:

$dsn = "mysql:host=localhost;dbname=database"; 
$username = "user"; 
$password = "pass"; 
$db = new PDO($dsn, $username, $password); 

$stmt = $db->prepare("SELECT * FROM (SELECT * FROM players WHERE Player_name = :playerone) 
s1 WHERE EXISTS (SELECT * FROM (SELECT * FROM players WHERE Player_name = :playertwo) s2 
WHERE s1.Team_name = s2.Opposing_team)"); 

$stmt->bindValue(':playerone', $playerOne); 
$stmt->bindValue(':playertwo, $playerTwo); 
$stmt->execute(); 
+0

你試圖做什麼,我不明白的事情。你在做什麼是不允許的,你需要對這3個查詢做什麼,並且你只需要準備1個查詢,即使它有子查詢 – 131

+1

你知道PDO準備語句如何工作嗎?你有什麼想法**佔位符**?你的$ sqlPlayerOne變量沒有顯示任何使用「bindParam/bindValue之類」的標誌 –

+0

這讓人困惑。您編輯問題以提出相當不同的問題,然後接受一個答案,既不解釋原始代碼的錯誤,也不解釋PDO語法。我希望你能夠理解準備好的語句的基礎知識,而不是盲目地將代碼粘貼到你的項目中;-) –

回答

1

您需要將$ playerOne,$ playerTwo綁定到準備好的語句中作爲參數。http://php.net/manual/en/mysqli.prepare.php

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

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

/* create a prepared statement */ 
$stmt = $mysqli->prepare("SELECT * FROM (SELECT * FROM players WHERE Player_name = ?) s1 
WHERE EXISTS (SELECT * FROM (SELECT * FROM players WHERE Player_name = ?) s2 WHERE s1.Team_name = s2.Opposing_team)") 

    /* bind parameters for markers */ 
    $stmt->bind_param("ss", $playerOne, $playerTwo); 

    /* execute query */ 
    $stmt->execute(); 
0

準備報表的總體列機制是在所有支持的數據庫擴展相同:

  • 更換號碼或字符串文字(我的意思是,文字,而不是隨機的代碼片段)內的SQL與佔位符,基於位置的?或命名:username(不要混合,挑一個)
  • 準備通過調用查詢接收SQL作爲參數
  • 的適當函數
  • 通過調用相應功能的接收值paremeter

所以,如果你是對的在庫MySQLi做執行準備好的查詢,切換到PDO將不需要在你的邏輯的變化。但是,您的代碼示例建議您使用:您沒有使用準備好的語句:沒有佔位符,沒有數據在單獨的通道中...我可以看到variable interpolation in double quoted strings,但這是PHP功能,不是SQL功能。因此,分離代碼和數據以及防止SQL注入是完全沒有用的。

我懷疑根本的誤解並不完全確定PHP和SQL如何交互。答案是,他們不是:他們是完全不同的計算機語言,他們是由完全不同的程序執行的。唯一的關係是你用前者來生成後者。不管你做什麼,最後你只需要向數據庫服務器提交一個字符串(即純文本)。如何生成該文本是無關緊要的,因爲字符串沒有記憶。