5

私は自分のWebサイトを保護されていないMySQLクエリからmysqliプリペアドステートメントに作り直してきましたが、これが得られるまですべてうまくいきました。プリペアドステートメントのパラメーターにデータが提供されていません。

if(empty($err)) {
    $pSETQuery  = NULL;
    if(!empty($_POST['password'])) {
        $pSETQuery .= ", password = ?";
    }
    if($session->isSuperuser()) {
        $pSETQuery .= ", usertype = ?";
    }
    if(!($stmt = $database->prepare("UPDATE user SET username = ?, email = ? $pSETQuery WHERE UserId = ?"))) {
        $err[] = "PREPARE FAILED.";
    }
    $stmt->bind_param("s", $_POST['username']);
    $stmt->bind_param("s", $_POST['email']);
    if(!empty($_POST['password'])) {
        $stmt->bind_param("s", $_POST['password']);
    }
    if($session->isSuperuser()) {
        $stmt->bind_param("s", $_POST['usertype']);
    }
    $stmt->bind_param("i", $_POST['userid']);
    if(!$stmt->execute()){
        $err[] = "Execute failed. ERROR: " . $stmt->error;
    }

}
4

4 に答える 4

6

発生しているエラーは、次の行が原因です。

$stmt->bind_param("s", $_POST['username']);
$stmt->bind_param("s", $_POST['email']);

呼び出すことができるのはbind_param()1 回だけで、SQL にプレースホルダーがあるため、正確な数の値を指定する必要があります。この関数は適切に設計されていません。これが、人々が PDO を好む主な理由の 1 つです。

この問題を解決するには、バインドするプレースホルダー、型、変数の 3 つを動的に準備する必要があります。このようなクエリを動的に作成する方法は次のとおりです。

if(empty($err)) {
    $pSETQuery  = '';
    $types = 'sss'; // for the three constant placeholders
    $data = [$_POST['username'], $_POST['email']];
    if(!empty($_POST['password'])) {
        $pSETQuery .= ", password = ?";
        $types .= 's'; //concat one more
        $data[] = $_POST['password'];
    }
    if($session->isSuperuser()) {
        $pSETQuery .= ", usertype = ?";
        $types .= 's'; //concat one more
        $data[] = $_POST['usertype'];
    }
    $data[] = $_POST['userid']; // for UserId
    
    $stmt = $database->prepare("UPDATE user SET username = ?, email = ? $pSETQuery WHERE UserId = ?");
    $stmt->bind_param($types, ...$data);
    $stmt->execute();
}
于 2020-12-09T12:41:17.607 に答える
1

Zend フレームワークを使用していますか? Php と Zend の間のバージョンの問題である可能性があります。Zend Framework 1.8.3 での挿入または更新で同じエラーが発生した PHP 5.3 + で問題が発生しました。

その場合、解決策の 1 つは、コネクタをデータベースに変更することです。これを試してください、それは私のために働きます:

$db = new Zend_Db_Adapter_Pdo_Mysql(array(
    'host'     => '127.0.0.1',
    'username' => 'webuser',
    'password' => 'xxxxxxxx',
    'dbname'   => 'test'
));
于 2012-10-01T12:47:37.270 に答える
-1

同じ問題を解決する方法を見つけました。

これは、MySQLに渡された値でしたNULL。この列NULLをテーブル定義に含めることはできませんが...

于 2013-03-18T17:58:10.990 に答える
-1

「プリペアドステートメントのパラメーターにデータが提供されていません」は、ステートメントは正常ですが、bind_paramに提供している変数の少なくとも1つが期待どおりに存在しないことを意味します。$ _POSTを出力して何が起こっているかを確認し、最終的に$ pSETQuery='';を設定します。ヌルにしないでください!

$_POST['username']
$_POST['email']
$_POST['password']
$_POST['usertype']
$_POST['userid'] // this one is the one I would really watch after, how do you tell the userid if the user is not logged ( i assume that from email, passwrod and might be wrong)
于 2012-09-29T23:07:58.803 に答える