Mohammad Faizan Khan Mohammad Faizan Khan - 18 days ago 5
PHP Question

Invalid parameter number: number of bound variables does not match number of token

So many question with this title but none of them able to solve my problem and I dont know WTH?
This is a simple code php adding data to a table

global $connPDO;
ini_set('date.timezone', 'Asia/Karachi');
$date = date('Y-m-d H:i:s');

$sql = "INSERT INTO `pqa` VALUES (null, :ProId, :ProQuestion, null, '$date', null)";
$queryInsert = $connPDO->prepare($sql);

try {
//Post contain $_POST["ProId"], $_POST["ProQuestion"];
$querySuccess = $queryInsert->execute($_POST);
echo $querySuccess;
}
catch(Exception $e) {
echo '<h1>An error has ocurred.</h1><pre>', $e->getMessage() ,'</pre>';
}


Catch block is not executing but giving error.

var data = {
"action" : "SaveProjectNewQuestion",
"ProId" : 1,
"ProQuestion" : $jqueryLib("#NewQuestion").val()
};
$jqueryLib.ajax({
url : "ESP.php",
type : "POST",
data : data,
success : function(data, textStatus, XMLHttpRequest) {
console.log(data);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(textStatus, errorThrown);
}
});


Amazingly success log showing this warning and no data has inserted also.


( ! ) Warning:
PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number:
number of bound variables does not match number of tokens in
C:\wamp\www\ESP\ESP.php on line
5621............................

Answer

When you're doing

$queryInsert->execute($_POST);

you're trying to bind everything in the global post-array with their respective indexes in the array as placeholder. When you submit your ajax, you're sending the following data

var data = {
    "action" : "SaveProjectNewQuestion",
    "ProId" : 1,
    "ProQuestion" : $jqueryLib("#NewQuestion").val()
};

Here there are three items, but you're only trying to bind two of them, causing there to be a missmatch in the number of binds and number of values, even if the two indexes you're trying to bind match the name of the placeholders - because your action isn't a placeholder in the query.

Generally I'd avoid doing like that, using the entire POST-array. It's only two variables to bind, I'd rather just bind them directly, like this

$queryInsert->execute(array("ProId" => $_POST['ProId'], 
                            "ProQuestion" => $_POST["ProQuestion"]));