PDO: использование одной и той же переменной привязки несколько раз
у меня проблема с подготовленными инструкциями PDO, где, если вам нужно использовать одну и ту же переменную привязки несколько раз, запрос не будет проверять.
пример:
$params = array (
':status' => $status,
':userid' => $_SESSION['userid']
);
$stmt = $pdo->prepare ('
INSERT INTO
tableName
( userId, status )
VALUES
( :userid, ":status" )
ON DUPLICATE KEY UPDATE
status = ":status"
');
if ( ! $stmt->execute ( $params ))
{
print_r( $stmt->errorInfo ());
}
редактировать: значение $params
являются:Array ( [:status] => PAID [:userid] => 111 )
Изменить 2:
Я заметил, что вместо исходных значений, вместо userid,0 вставляется, и вместо статуса вставляется пустая строка.
4 ответов
ключи массива не должны содержать двоеточие. Двоеточие предназначено исключительно для PDO, чтобы знать, что ниже приведен именованный параметр.
$params = array (
':status' => $status,
':userid' => $_SESSION['userid']
);
должно быть
$params = array (
'status' => $status,
'userid' => $_SESSION['userid']
);
отлично работает для меня. Е. Г.
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
setup($pdo);
echo 'client version: ', $pdo->getAttribute(PDO::ATTR_CLIENT_VERSION), "\n";
echo 'server version: ', $pdo->getAttribute(PDO::ATTR_SERVER_VERSION), "\n";
echo "before:\n";
foreach( $pdo->query('SELECT * FROM tmpTableName', PDO::FETCH_ASSOC) as $row ) {
echo join(', ', $row), "\n";
}
$status = 1;
$_SESSION['userid'] = 'foo';
$params = array (
'status' => $status,
'userid' => $_SESSION['userid'],
);
$stmt = $pdo->prepare ('
INSERT INTO
tmpTableName
(userId, status)
VALUES
(:userid, :status)
ON DUPLICATE KEY UPDATE
status = :status
');
if ( ! $stmt->execute ( $params ))
{
print_r( $stmt->errorInfo ());
}
echo "after:\n";
foreach( $pdo->query('SELECT * FROM tmpTableName', PDO::FETCH_ASSOC) as $row ) {
echo join(', ', $row), "\n";
}
function setup($pdo) {
$pdo->exec('
CREATE TEMPORARY TABLE tmpTableName (
userId varchar(32),
status int,
unique key(userId)
)
');
$pdo->exec("INSERT INTO tmpTableName (userId,status) VALUES ('foo', 0)");
$pdo->exec("INSERT INTO tmpTableName (userId,status) VALUES ('bar', 0)");
}
печать
client version: mysqlnd 5.0.10 - 20111026 - $Id: b0b3b15c693b7f6aeb3aa66b646fee339f175e39 $
server version: 5.5.25a
before:
foo, 0
bar, 0
after:
foo, 1
bar, 0
на своей машине
ты не будешь звонить в bindParam
метод в любом месте, почему? Как раз перед тем, как вы призываете execute
, попробуйте добавить
$stmt->bindParam(':userid', $_SESSION['userid'], PDO::PARAM_INT);
$stmt->bindParam(':status', $status, PDO::PARAM_STR);
а потом просто позвоните $stmt->execute();
посмотрим, как это работает для вас. Также включите сообщения об ошибках до полного, и после создания экземпляра экземпляра PDO добавьте это $db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
для обеспечения ошибок всегда выбрасываются.