2012-07-27 49 views
4

我知道標題聽起來很可笑,但我已經花了幾個小時的時間進行了研究,只是想知道PDO最終是沒有明顯解決方案的越野車......我致力於開放一個。我也願意接受我的代碼有缺陷。PDO和PHP/MySQL:PDO準備好的語句有什麼問題?

使用PHP 5.2/Ubuntu的,此代碼的工作(不使用預處理語句/打開注射):

$sql ="SELECT COUNT(*) FROM property p 
INNER JOIN property_attribute pa ON p.property_id = pa.property_id 
INNER JOIN property_area pc ON p.property_id = pc.property_id 
WHERE pa.attribute_value_id 
    IN (
     SELECT av.attribute_value_id 
     FROM attribute_value av 
     INNER JOIN attribute a ON av.attribute_id = a.attribute_id 
     WHERE a.name LIKE '$attributes' 
     AND av.value LIKE '$values' 
    ) 
ORDER BY p.price ASC"; 
$params = array(); 
$rHowManyPages = Listings::HowManyPages($sql, $params); 

但是,使用PDO的精彩準備語句:

$sql ='SELECT COUNT(*) FROM property p 
INNER JOIN property_attribute pa ON p.property_id = pa.property_id 
INNER JOIN property_area pc ON p.property_id = pc.property_id 
WHERE pa.attribute_value_id 
    IN (
     SELECT av.attribute_value_id 
     FROM attribute_value av 
     INNER JOIN attribute a ON av.attribute_id = a.attribute_id 
     WHERE a.name LIKE :attributes 
     AND av.value LIKE :values 
    ) 
ORDER BY p.price ASC'; 
$params = array(':attributes' => $attributes, ':values' => $values); 
$rHowManyPages = Listings::HowManyPages($sql, $params); 

它的工作原理,還挺。這裏的Spartanic瘋狂部分:傳遞1/5刷新相同的數據,PDO給出了這樣的錯誤:

TEXT: SQLSTATE[HY093]: Invalid parameter number 

這是隨機的!如何和爲什麼?

回答

5

是否有可能爲命名參數提供的值之一包含問號?我遇到了一個問題,但那是很久以前的事了。 (我當然認爲他們現在已經修好了)。

在我有限的經驗中,PDO對「命名參數」的支持有點粗略。

一方面,您不能在語句的多個位置使用相同的命名參數,每個命名參數的佔位符名稱必須是唯一的,並且只能使用一次。而且,這一切將水下命名的爭論帶來的巨大好處之一。

我認爲我遇到的問題是一個值中的問號字符,以及不能多次引用一個命名參數(我還沒有證實這一點)是由於PDO「命名參數」支持是一個事後支持立場爭論;本質上,它看起來像「命名參數」被轉換成位置參數。

當命名參數包含下劃線字符時,我也遇到了一些奇怪現象。

我的解決方法是(ACCCKKK!)使用位置參數而不是命名參數。

(雖然我很討厭用位置參數,它爲我工作。)

(我看不出有什麼錯在你表明將佔所觀察到的行爲的代碼。顯然,是其他代碼,你沒有顯示。)

此外,你可能想驗證你的$params數組只包含兩個元素;當我的數組有一個「額外」不匹配的元素時,我有相同的錯誤消息。然後,再次,在我的代碼中,我放棄了使用標量,並分別綁定每一個,而不是讓PDO把它弄糟。 (不是我一個問題,那就是模式,我太熟悉了在Perl DBI而不是與調試的問題渣土,我的工作他們周圍。)


注:通過位置參數,我的意思是用一個問號代替名字:

$sql = " ... 
    WHERE a.name LIKE ? 
    AND av.value LIKE ? 
... "; 

$sth->bindParam(1, $attributes); 
$sth->bindParam(2, $values); 
+2

[This Drupal bug](https:// drupal。org/node/1350346)顯示了類似的問題,如果你的值有':'在其中。 – 2012-07-27 22:20:57

+0

@Brendan:非常好的一點,我完全可以看到綁定數據中的冒號字符如何導致類似於我用問號字符所遇到的問題。 – spencer7593 2012-07-27 22:42:53

+0

@ spencer7593一個傑出的迴應。我不知道如何在沒有很多重構的情況下讓它工作(我有一個班正在做我所有的DBO準備和執行的內容),但這肯定會有很多答案。謝謝。 – 2012-07-27 23:16:57