php pdo:prepare()vs transactions

时间:2011-11-16 20:47:01

标签: php transactions pdo prepared-statement

prepare()transactions互相排斥吗?我有很多查询,我构建然后执行,所以听起来像使用事务是我想要的;但我在prepare.statment页面上读到,使用bindParam方法消除了SQL注入。有两种方法可以做到吗?

以下是我现在的代码示例(可能是也可能不正确):

$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(…),并在echo "connected"的末尾添加了try(并抓住了位),它回声“连接”,所以它是连接。但是在“连接”之后它会打印出该错误消息,因此在成功连接后会出现问题。

编辑3 :我添加了

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

它打印了表格的第一行,所以确定它正在连接。

2 个答案:

答案 0 :(得分:1)

  • “互相排斥吗?”:不,如你所示,是一种“函数声明”,事务就像一个(OS)进程,函数运行。
  • “是否允许变量?”:我认为您必须开始检查PHP函数record_data($q,$a,$k):出现错误。尝试在函数开头添加global $record_data;

一般性评论:PDO的主要优点是为每个单个SQL语句捕获错误(通过PHP错误行或返回SQL错误消息)。 请参阅pdo.begintransactionpdo.commitpdo.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();

答案 1 :(得分:0)

您正在使用未在函数范围内定义的变量。只需使用:

global $record_data;

作为函数的第一行,它将起作用。