7

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が挿入され、statusの代わりに空の文字列が挿入されることに気づきました。

4

4 に答える 4

8

問題は:statusの周りの引用符でした。引用符を削除し、すべてが良好です。

于 2012-08-20T11:34:39.667 に答える
3

配列キーにコロンを含める必要はありません。コロンは、純粋にPDOが、後に続くものが名前付きパラメーターであることを認識するためのものです。

$params = array (
    ':status' => $status,
    ':userid' => $_SESSION['userid']
);

する必要があります

$params = array (
    'status' => $status,
    'userid' => $_SESSION['userid']
);
于 2012-08-20T10:36:36.013 に答える
2

私にとってはうまくいきます。例えば

<?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

私のマシンで

于 2012-08-20T11:36:30.153 に答える
1

どこにもメソッドを呼び出さないのは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);て、エラーが常にスローされるようにします。

ドキュメントは便利なものです

于 2012-08-20T10:38:16.343 に答える