hello i've got a question about bind_param every code is works but not this one...probably dumb question..
$key = "`".implode("`, `",array_keys($notifikasi))."`";
echo $value = "'".implode("', '",array_values($notifikasi))."'";
$query = $dbcon->prepare("INSERT INTO `notifikasi` ($key) VALUES ($value)");
$query->bind_param("iiiis",$value);
$query->execute();
i've echo the value :
'1','1','2','3','profile.php?confirm=33'
i've put any number on bind_param still got this error:
mysqli_stmt::bind_param(): Number of elements in type definition string doesn't match number of bind variables
anyone can answer my misunderstanding?
[EDIT]
nevermind, i've found the solution :
use call_user_func_array()
mysqli bind_param for array of strings
thanks
The problem is you are trying to bind parameters when you didn't add any placeholder for them.
You should never trust user's input so I would suggest you not to populate column names from the input. I would fix column names in query:
$notifikasi = [1, 2, 'profile'];
$query = $dbcon->prepare("INSERT INTO `notifikasi` (col1, col2, col3) VALUES (?, ?, ?)");
$query->bind_param("iis", $notifikasi);
Related
I've been stuck on this for hours. I have to manipulate a database with a website using php. I'm trying to add data from a form to my database but it gives me :
PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in...
This is what's creating the problem.
$sqlQuery = 'INSERT INTO succursale(adresse, ouverture, fermeture, ouvert_raison) VALUES (:adresse, :ouverture, :fermeture, :ouvert_raison)';
$req = $conn->prepare($sqlQuery);
$req-> execute(array($_POST['adresse'], $_POST['ouverture'], $_POST['fermeture'], $_POST['ouvert_raison']));;
I've looked for people with a similar problem but the answers given do not match with my situation.
You are using named placeholder in your prepared statement. This means you'll need to pass those as an associative index. Otherwise the statement will not know which value to bind to the placeholder
$req-> execute(array(
':adresse' => $_POST['adresse'],
':ouverture' => $_POST['ouverture'],
':fermeture' => $_POST['fermeture'],
':ouvert_raison' => $_POST['ouvert_raison'],
));
If you don't want to do this, you can change the named placeholders to a ?
$sqlQuery = 'INSERT INTO succursale(adresse, ouverture, fermeture, ouvert_raison) VALUES (?, ?, ?, ?)';
on the frontend I am using JQuery Validate, and I pass the following to the backend
data: {
'field1': $("input[name='field1']:checked").val(),
'field2': $("input[name='field2']:checked").val(),
'field3': $("#field3").val(),
'field4' : $("#field4").val(),
'field5' : $("#field5").val(),
'field6' : $("#field6").val()
}
The first three fields are required, so they will always have a value. The next three are optional, so they may not have a value. In my PHP file, I do something like this for required fields
if (!empty($_POST["field1"])) {
$field1 = filter_var($_POST["field1"], FILTER_SANITIZE_STRING);
array_push($inputArray, $field1);
} else{
$errors['field1'] = 'Please select field1';
}
And for optional fields I do
if (!empty($_POST['field4'])) {
$field4 = filter_var($_POST["field4"], FILTER_SANITIZE_STRING);
array_push($inputArray, $field4);
}
By the end of this, I have an $inputArray which may contain between 3-6 values which is passed to my database file. Here, I am doing something like this
$stmt = $dbh->prepare("INSERT INTO database_table(Field1, Field2, Field3, Field4, Field5, Field6) VALUES (?, ?, ?, ?, ?, ?)");
$stmt->bindParam(1, $this->inputArray[0]);
Now that will be fine for the first three, but if I then try an optional element and its not there, an error will be thrown.
Whats the best way to handle this type of situation? In the PHP file, should I always push an empty value for the three if statements that are optional fields e.g.
else {
array_push($inputArray, '');
}
I know off several solutions I could potentially use, just wanted to get opinions from others as to how they would handle it.
Thanks
I've found that the best way of handling this sort of problem is to dynamically build the query. This sort of approach is easier when you use an associative $inputArray. As such, instead of doing
array_push($inputArray, $field1);
Do
$inputArray['field1Name'] = $field1;
replacing "field1" with the appropriate value for each field.
That way you can build your query like this:
$qry = "INSERT INTO database_table(";
$qry .= implode(',', array_keys($inputArray)); //append a comma separated list of field names.
$qry .= ") VALUES("
$qry .= trim(str_repeat('?,', count($inputArray)), ','); //append ?, for each element in the array and trim the trailing comma
$qry .= ')';
$stmt = $dbh->prepare($qry);
$stmt->execute( array_values($inputArray)); //Execute the query with the values from the input array
In this way the number of arguments in the sql query is dynamic and based on the number of fields that were filled out.
This could be easily changed to use named parameters instead of ? but the general concept is the same.
I can convert the echo'ed output in to an SQL statement that executes in phpMyAdmin going...
From this:
INSERT INTO crumbs (ip_address,ip_address_2,device_info,user_id,connections) VALUES(?,?,?,?,?)Value:'00.000.000.000', '00.000.000.000', 0,0000, 1
Into this:
INSERT INTO crumbs (ip_address,ip_address_2,device_info,user_id,connections) VALUES('00.000.000.000', '00.000.000.000', 0,0000, 1)
It inserts the data in to the DB, no errors, however it executes through PHP-PDO...
With:
SQLSTATE[HY093]: Invalid parameter number
The code:
$columns = '('.implode(',', array_keys($user_connection)).''.",user_id,connections)";
$inserts="(".implode(',',array_fill(0,count($user_connection)+2, '?')).")";
$values = implode(', ',($user_connection)).",$user_id, 1";
$sql_insert = "INSERT INTO crumbs ".$columns." VALUES".$inserts;
$stmt = $this->_db->prepare($sql_insert);
$stmt->execute(array($values));
Edit-Adding $user_connection
$user_connection [ 'ip_address'] = "'".$_SERVER['REMOTE_ADDR']."'";
$user_connection [ 'ip_address_2']="'".$_SERVER['HTTP_X_FORWARDED_FOR']."'";
$user_connection ['device_info']=0;
The error occurs during the execution of the SQL code. I've gone over all the examples and found nothing that's equivalent, I'm thinking it's something simple I'm missing (a rule?) since the code executes locally.
You have to do something like this:
// ..code..
$values = $user_connection;
$values[] = $user_id;
$values[] = 1;
// ..code..
$stmt->execute($values);
Explanation of the problem:
When you have multiple ? placeholders, you can pass each value to be bounded as the values of an array (See Example #3 from the manual).
Now, since you are using implode, $values will be a single string, something like
'192.168.0.1', '8.8.8.8', 0, 'userid', 1
That means that when you call execute(array($values)), it will, in fact, bound it like this (representation-only, it's not really like this)
INSERT INTO crumbs (ip_address,ip_address_2,device_info,user_id,connections) VALUES ("'192.168.0.1', '8.8.8.8', 0, 'userid', 1", ?, ?, ?, ?)
because you only sent and array that has one value: the implosion of the other array. Since you didn't provide the same amount of values (1) as you have placeholders (5), you end up with
Invalid parameter number
I am having an error in mysql and php My code:
$stmt->prepare("INSERT `tablename` (col1,col2,col3) VALUES (?,?,?)");
$stmt->bind_param('sss',$_POST['data'],$sub,$yaxis);
$stmt->execute();
My errors:
Warning: mysqli_stmt::bind_param() [mysqli-stmt.bind-param]: Number of variables doesn't match number of parameters in prepared statement.
But I have passed 3s and 3 arguments in bind_param. Why is this error occuring?
use the index of parameter since you did not specify it by name.
$data = $_POST['data'];
$stmt->prepare("INSERT `tablename` (col1,col2,col3) VALUES (?,?,?)");
$stmt->bind_param(1,$data);
$stmt->bind_param(2,$sub);
$stmt->bind_param(3,$yaxis);
$stmt->execute();
but if you want it by name then you have to specify its parameter name instead of using question mark
$data = $_POST['data'];
$stmt->prepare("INSERT `tablename` (col1,col2,col3) VALUES (:sss,:par1,:par2)");
$stmt->bind_param(":sss",$data);
$stmt->bind_param(":par1",$sub);
$stmt->bind_param(":par2",$yaxis);
$stmt->execute();
Are you sure you have value in your $_POST['data'] , Instead of directly passing form values to bind_param you can check if it is null or not.Also i noticed your insert query is wrong
if(!empty($_POST['data'])){
$mydata=$_POST['data'];
}else{
$mydata='No values';
}
$stmt->prepare("INSERT into `tablename` (col1,col2,col3) VALUES (?,?,?)");//Query wrong
$stmt->bind_param('sss',$mydata,$sub,$yaxis);
$stmt->execute();
Well, either $_POST has more than one variable assigned to it, or it has none.
This will print the contents of the entire $_POST array:
print_r($_POST);
Okay, I know this makes me sound stupid but the error was caused by an undefined variable farther up in the script, which I have now fixed. I thought it would not affect this part of the script, but it did. All the answers posted are great, but because of my fault they do not answer the question.
I'm having a slight problem with the PHP PDO library and prepared statements. As far as I can see the prepared statement below should work but it doesn't, instead I get: "PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens".
My PHP code for this section looks like:
$sql = 'INSERT INTO '.POLYGON_TABLE.' (user_id, polygon, polygon_type) VALUES (:userId, PolygonFromText(\'POLYGON((:polygonArea))\'), :polygonType)';
$sth = $this->pdo->prepare($sql);
$sth->bindValue(':userId', $polygon->getUserId(), \PDO::PARAM_INT);
$sth->bindValue(':polygonArea', $polygon->getPolygonAsText(), \PDO::PARAM_STR);
$sth->bindValue(':polygonType', $polygon->getPolygonType(), \PDO::PARAM_STR);
if($sth->execute()) {
return true;
} else {
return false;
}
I have done a var_dump of $polygon->getUserId(), $polygon->getPolygonAsText() and $polygon->getPolygonType() and get the following:
string(1) "1"
string(226) "53.897910476098765 -1.739655277929728, 53.865530797116 -2.080231449804728, 53.67235280490181 -2.006073734960978, 53.68862047002787 -1.621552250585978, 53.89305512284903 -1.539154789648478, 53.897910476098765 -1.739655277929728"
string(7) "commute"
The issue is with $polygon->getPolygonAsText() as commenting out this particular bindValue call and the PolygonFromText(\'POLYGON((:polygonArea))\') from the SQL statement causes the query to work.
I'm now completely at a loss. Anyone know what's wrong here? I can't see anything wrong with the text contained within $polygon->getPolygonAsText(). I have searched high and low for a solution to this and spent several hours this evening tinkering with the code but to no avail.
I have even tried the suggestions in these 2 stack overflow topics but they didn't work either:
Invalid parameter number on PDO Prepared Statement
PHP PDO prepared statements
Any help would be much appreciated...
Did you try passing in the entire expression as the bind value?
$sql = 'INSERT INTO '.POLYGON_TABLE.' (user_id, polygon, polygon_type) VALUES (:userId, PolygonFromText(:polygonArea), :polygonType)';
$sth = $this->pdo->prepare($sql);
$area = sprintf("POLYGON((%s))", $polygon->getPolygonAsText());
$sth->bindValue(':userId', $polygon->getUserId(), \PDO::PARAM_INT);
$sth->bindValue(':polygonArea', $area, \PDO::PARAM_STR);
$sth->bindValue(':polygonType', $polygon->getPolygonType(), \PDO::PARAM_STR);
It appears that you're trying to use a named parameter inside a string:
PolygonFromText(\'POLYGON((:polygonArea))\')
This would be akin to doing something like this:
UPDATE foo SET bar = 'blah blah :wontwork blah blah'
What you should try instead is binding the whole string in the query:
PolygonFromText(:polygonArea)
And then including the rest of the string in the bound value:
$sth->bindValue(':polygonArea', 'POLYGON((' . $polygon->getPolygonAsText() . '))', \PDO::PARAM_STR);
Last resort you could do this:
$sql = "INSERT INTO ".POLYGON_TABLE." (user_id, polygon, polygon_type) "
."VALUES (:userId, PolygonFromText('POLYGON(". $polygon->$getPolygonAsText
.")'),:polygonType)";
But I think you should try the ? params first and see how that goes.
$sql = "INSERT INTO ".POLYGON_TABLE." (user_id, polygon, polygon_type) "
."VALUES (?, PolygonFromText('POLYGON(?)'), ?);";
$data = array($polygon->getUserId(), $polygon->getPolygonAsText(), $polygon->getPolygonType());
$query->execute($data);
Btw, I also think those single quotes around the POLYGON(?) function are dodgy... usually you don't quote a method call do you?