2011-11-16 107 views
4

prepare()transactions互斥嗎?我有很多我建立並執行的查詢,所以聽起來像使用事務是我想要的;但是我在prepare.statment頁面上看到,使用bindParam方法的頁面消除了SQL注入。有兩種方法可以做到這一點嗎?php pdo:準備()vs交易

下面的代碼我現在所擁有的(這可能會或可能不正確)的例子:

$dbhost=FOO; 
$dbuser=FOOBAR; 
$dbpass=RABOOF; 
$options=array(STUFF); 

$dbh = new PDO("mysql:host=$dbhost", $dbuser, $dbpass, $options); 
// I know this^works 

$dbh->beginTransaction(); 
$record_data = $dbh->prepare("UPDATE $db.$tbl SET :column=:value WHERE `key` = :key;"); 

function record_data($q,$a,$k){ 
    $record_data->bindParam(':column', $q); 
    $record_data->bindParam(':value', $a); 
    $record_data->bindParam(':key', $k); 
    $record_data->execute(); 
} 

// $pairs is an array with ~50 objects/rows 
foreach($pairs as $pair){ 
    list($qstn , $ans) = explode('=', $pair); 
    switch($qstn){ 
     case 1: if(something) record_data($qstn,$ans,$key); break; 
     case 2: if(something) record_data($qstn,$ans,$key); break; 
     case 3: if(something) record_data($qstn,$ans,$key); break; 
     // more 
     default: record_data($qstn,$ans,$key); break; 
    } 
} 
$dbh->commit(); 

當我嘗試了完整的代碼,我得到了No connection could be made because the target machine actively refused it.通常我看到這樣,當一個消息我的連接信息不正確(或者帳戶設置不當/按我的預期)。但我單獨測試了PDO連接,它工作正常。所以我可能做了一些其他的錯誤。

編輯:在prepare()允許的變量?

編輯2:我添加try{}$dbh = PDO(…)周圍,並在try結束時加入echo "connected"(和確實捕捉位),並將其回顯「連接」,因此它被連接。但「連接」後,它會打印該錯誤消息,所以問題發生在連接成功後。

編輯3:我添加

$dbRS = $dbh->query("SELECT * FROM `database`.`table`;"); 
$row = empty($dbRS) ? false : $dbRS->fetch(PDO::FETCH_ASSOC); 
print_r($row); 

,並打印表格的第一行,所以確保它的連接。

+0

檢查您的登錄的東西。我可以說:Transactions和PreparedStatements一起工作 – KingCrunch

+0

@KingCrunch:我確定登錄信息是正確的(在代碼中註明) – jacob

+1

在事務內準備/執行語句並直接在同一個語句中執行查詢沒有區別事務 - 最終他們都只是被執行的查詢。準備好的語句可以簡單地以比每次執行「新」語句少得多的開銷重用。 –

回答

0

您正在使用未在函數範圍內定義的變量。簡單地使用:

global $record_data; 

作爲函數的第一行,它將工作。

1
  • 「是互斥的嗎?」:不,如您所示,是一種「函數聲明」,事務就像一個函數運行的(OS)過程。
  • 「變量是否允許?」:我認爲你必須開始檢查你的PHP函數record_data($q,$a,$k):有錯誤。嘗試在功能開始處添加global $record_data;

總評:PDO的主要優點是捕獲錯誤(由PHP錯誤行或返回SQL錯誤消息)爲每個單一SQL statment。 參見pdo.begintransaction,pdo.commit,pdo.rollbackpdo.error-handling

例子:

$dbh->beginTransaction(); 
/* Do SQL */ 
$sth1 = $dbh->exec("CREATE TABLE xyz (..)"); 
$sth2 = record_data($qstn1,$ans1,$key1); 
$sth2 = record_data($qstn2,$ans2,$key2); 
/* Commit the changes */ 
$dbh->commit();