2013-02-11 65 views
4

$字段中定義是一個數組,印刷後得到的值,如:警告:PDOStatement對象::執行():SQLSTATE [HY093]:無效參數數:參數沒有在... FILETEXT

Array ([first_name] => Nisse [last_name] => Example [ssn] => 198306205053 [address] =>   Stockholm, Sverige [phone_number] => 54654987321546 [latitude] => 55.717089999999999 [longitude] => 13.235379) 

我從我的數據類調用更新功能,像這樣:

DataManager::update_user($fields, $user_data['id']; 

但我得到的錯誤:

Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in...filetext

我已籤小號其他類似的線程,但我想我錯過了一些基本概念,因爲我仍然無法找到答案。有7個的7項在我的數組,據我所看到的,如果我定義所有的值,我可以在SQL工作臺完美地運行,即:

UPDATE users SET first_name = 'Kalle', last_name = 'Anka', ssn = 242345234, address = 'Stockholm', phone_number = 53423434, latitude = 17.189889231223423423424324234, longitude = 109.234234 WHERE id = 4 

我曾嘗試編寫的PDO語句,其中$ user_id設置爲特定值並且也沒有緯度/經度參數。

如果我忘記了任何關鍵信息,只需指出它,我就能得到它。地址是varchar和緯度/經度浮動數據庫btw。使用MYSQL。

以下功能:

public static function update_user($fields, $user_id) 
{ 
    $db = self::_connect(); 

    $st = $db->prepare("UPDATE users SET first_name = ?, last_name = ?, ssn = ?, address = ?, phone_number = ?, latitude = ?, longitude = ? WHERE id = '{$user_id}'"); 
    $st->execute($fields); 

    return ($st->rowCount()) ? true : false; 
} 
+1

我不記得如果execute()不正確地處理關聯數組,如果參數未被命名(使用'?'而不是':first_name',對於ex)。如果你執行'$ st-> execute(array_values($ fields));'剝離關聯關鍵字,它會起作用嗎? – 2013-02-11 18:49:15

+0

@MichaelBerkowski:你說的沒錯。當使用位置參數時,您必須使用0索引整型鍵。此外,如果您使用命名參數,則語句中的佔位符和傳遞給執行的參數的字符串鍵都必須匹配,並以':'作爲前綴。 – prodigitalson 2013-02-11 18:53:52

+0

@prodigitalson我認爲可能是這樣,但沒有提到[在文檔](http://php.net/manual/en/pdostatement.execute.php),我發現。 – 2013-02-11 18:55:12

回答

6

如果使用位置參數,參數傳遞給​​陣列必須是順序數組。同樣,如果您使用命名參數,則該數組必須是關聯數組。

這裏有一個測試,以確認該行爲:

$stmt = $db->prepare("SELECT ?, ? ,?"); 

$params = array('a', 'b', 'c'); 
// OK 
if ($stmt->execute($params)) { 
    print_r($stmt->fetchAll()); 
} 

$params = array('A'=>'abc', 'B'=>'def', 'C'=>'ghi'); 
// ERROR! 
if ($stmt->execute($params)) { 
    print_r($stmt->fetchAll()); 
} 

$stmt = $db->prepare("SELECT :A, :B, :C"); 

$params = array('a', 'b', 'c'); 
// ERROR! 
if ($stmt->execute($params)) { 
    print_r($stmt->fetchAll()); 
} 

$params = array('A'=>'abc', 'B'=>'def', 'C'=>'ghi'); 
// OK 
if ($stmt->execute($params)) { 
    print_r($stmt->fetchAll()); 
} 

注意,在PHP的當前版本中,關聯數組鍵必須與:爲@prodigitalson意見前綴。 :前綴在舊版本的PHP中用於數組鍵中。

另外值得一提的是,當我嘗試在單個查詢中混合位置參數和命名參數時,遇到了錯誤和不可預知的行爲。您可以在您的應用中使用不同的查詢中的任意一種樣式,但爲給定的查詢選擇了一種或另一種樣式。

+1

非常好,徹底的回答這個問題。我剛剛通過試圖瞭解不同行爲的測試來解決問題,並且您提出了幾點優點。這裏有一些該死的能幹的人...... – HolyMackerel 2013-02-11 19:11:38

相關問題