php pdo: prepare () против транзакций - PullRequest
4 голосов
/ 17 ноября 2011

Являются ли 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 (и сделал бит перехвата), и это echo'd "подключено ", так что это соединение. Но после «подключен» он печатает это сообщение об ошибке, поэтому проблема возникает после успешного подключения.

РЕДАКТИРОВАТЬ 3 : я добавил

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

и он напечатал первый ряд таблицы, так что наверняка он подключается.

Ответы [ 2 ]

1 голос
/ 11 мая 2012
  • «Являются ли взаимоисключающие?»: Нет, как вы показываете, это своего рода «объявление функции», а транзакция похожа на процесс (ОС), в котором выполняется функция.
  • «Разрешены ли переменные?»: Я думаю, что вы должны начать проверку своей функции PHP record_data($q,$a,$k): произошла ошибка.Попробуйте добавить global $record_data; в начале функции.

Общие комментарии: основное преимущество PDO - захват ошибок (по строке ошибок PHP или возвращающихся сообщений об ошибках SQL) для каждый отдельная SQL-оценка.См. pdo.begintransaction , pdo.commit , pdo.rollback и pdo.error-processing .

Пример:

$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();
0 голосов
/ 17 ноября 2011

Вы используете переменные, которые не были определены в области действия функции.Просто используйте:

global $record_data;

в качестве первой строки функции, и она будет работать.

...