bind_param number arguments not equal to variables - php

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.

Related

insert into multiple rows PDO

i am struggling with the code to insert into multiple rows.
but ended up getting warnings
$rows = array(1,2,3,4,5,6)
$stmt = $connect->prepare("INSERT INTO t_worker_history (uid) VALUES (?)");
foreach($rows as $insert) {
$stmt->execute($insert);
}
Warning: PDOStatement::execute() expects parameter 1 to be array, string given in
As the message says, the first parameter needs to be an array, so just put the $insert value into one:
$stmt->execute(array($insert));
See the manual. The reason the parameter needs to be an array is to allow for multiple parameters to be bound to placeholders.

bind_param number of elements doesn't match number of element array

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);

How to UPDATE a MySQL table from an HTML form with PHP PDO prepared statements

I’m working on an app and I am getting stuck updating values in a MySQL database table.
When I use the single value version of the name attribute (i.e. name="value1") everything works fine. But, when I use the array syntax (name="value[]") for the name attribute I get an error.
The error occurs right here:
$stmt = $conn->prepare("UPDATE students SET value=value+{$_POST['value']}");
The error is:
Error: Notice: Array to string conversion on line 8
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'value' in 'field list'
This is my PDOStatement::execute statement.
$stmt->execute(array("value", $_POST['value']));
This is my HTML:
<input class="input" id="id1" name="value[]" type="range">
<input class="input" id="id2" name="value[]" type="range">
<input class="input" id="id3" name="value[]" type="range">
The columns in my table are named value1, value2, value3 and so on.
Thanks for your comprehensive reaction. I didn't mentioned that the input must increase the database values. However, this is how I get it to work.
if(isset($_POST['value'])){
if(is_array($_POST['value'])) {
foreach($_POST['value'] as $key => $value) {
$stmt = $conn->prepare("UPDATE students SET value".($key+1)." = ? + value".($key+1)." ");
$stmt->execute(array($value));
}
}
With thanks to the guy who removed his answer but he give me the inspiration!
Warning: Never use anything from $_POST directly! Sanitize and validate all user input. What you see below is for demonstration purposes only. Without a WHERE clause in your query, the entire table will be updated.
When you do this in your HTML <input> elements:
name="value[]"
$_POST will receive an array for the $_POST element value. Thus,
$_POST['value'] //resolves to an array.
That is why you are getting an error (Error: Notice: Array to string conversion) when you do this:
$stmt = $conn->prepare("UPDATE `students` SET `value` = `value` +{$_POST['value']}");
Braces {} are typically used during string interpolations within double quotes. Your code is trying to turn an array in to a string.
You might try this instead:
$stmt = $conn->prepare("UPDATE `students` SET `value1` = `value1` + ?");
Or, this ...
$stmt = $conn->prepare("UPDATE `students` SET `value1` = `value1` + :value1");
Do not put user input directly into a prepared statement. The PHP PDO::prepare manual page states.
Prepares an SQL statement to be executed by the
PDOStatement::execute() method. The SQL statement can contain zero or
more named (:name) or question mark (?) parameter markers for which
real values will be substituted when the statement is executed. You
cannot use both named and question mark parameter markers within the
same SQL statement; pick one or the other parameter style. Use these
parameters to bind any user-input, do not include the user-input
directly in the query.
You need to do some processing of the array $_POST['values'] first. Sanitizing and validating the data is highly advisable and a best practice.
The data for your <input> elements is actually here.
$_POST['values'][0] //Resolves to a string.
$_POST['values'][1] //Resolves to a string.
$_POST['values'][2] //Resolves to a string.
The error Column not found: 1054 Unknown column 'value' in 'field list' suggests that you should use the name of an actual column in your table. By your own words, those field names are value1, value2, and value3.
When you use PDOStatement::execute, you can do this just to see if things are working in the ? way....
$stmt->execute([$_POST['values'][0]]) //PHP 5.4+
Or
$stmt->execute(array([$_POST['values'][0])) //PHP 5.3 and below
If you used named parameters, you can try this.
$stmt->execute(['value1' => $_POST['values'][0]]) //PHP 5.4+
Or
$stmt->execute(array('value1' => [$_POST['values'][0])) //PHP 5.3 and below
.... but I call that living dangerously. Sanitize and validate your inputs first.
If you ever get to the point of using MySQL stored procedures (say, for an e-commerce site) with your PDO prepared statements, look up PDOStatement::bindParam (must use variables with this) and PDOStatement::bindValue (can use general values, like string literals).
$stmt->bindValue(1, $variable);
$stmt->execute();
Or ...
$stmt->bindValue(:name, $variable);
$stmt->execute();
$stmt->bindParam(1, $variable); or $stmt->bindParam(:name, $variable); are mostly useful for using IN/OUT arguments with stored procedures.
Be careful. You will end up updating the entire table because there is no WHERE condition in your query! But, if you want all records to have the same value, that's how you can do it. :-) What would Edgar F. Codd say?
While it is possible to use a loop to solve the problem of using all three supposed $_POST['value'] elements, one still needs to ask why the entire table would need to be updated for each iteration.
I edited your answer to look like this.
if(isset($_POST['value']) && is_array($_POST['value']) && !empty($_POST['value']) && (count($_POST['value']) === 3)){
foreach($_POST['value'] as $key => $value) {
$num = ($key + 1);
$stmt = $conn->prepare("UPDATE `students` SET value{$num} = ? + value{$num}");
$stmt->bindValue(1, $value);
$stmt->execute();
}
}
While not comprehensive, at least better checking is being done. But, something like this could be better.
if(!isset($_POST['value']) || !is_array($_POST['value']) || empty($_POST['value']) || (count($_POST['value']) !== 3)){
throw new UnexpectedValueException("Something is wrong with the input in $_POST.");
}
foreach($_POST['value'] as $key => $value) {
$num = ($key + 1);
$stmt = $conn->prepare("UPDATE `students` SET value{$num} = ? + value{$num}");
$stmt->bindValue(1, $value);
$stmt->execute();
}

You have an error in your SQL syntax, but cant seem to trace error

I am using the following script to enter data into my database from a form. I have echo'd each of the values declared at the beginning and they are all coming across just fine.
include("connectmysqli.php");
echo '<link rel="stylesheet" href="http://towerroadacademy.co.uk/templates/rt_reflex_j16/css/template.css">';
if (isset($_GET['questionnaireID'])) {$questionnaireID = $_GET['questionnaireID'];}else {$questionnaireID = '';}
if (isset($_POST['newquestionnumber'])) {$questionnumber = $_POST['newquestionnumber'];}
if (isset($_POST['questionID'])) {$questionID = $_POST['questionID'];}else {$questionID = '';}
if (isset($_POST['question'])) {$question = $_POST['question'];}else {$question = '';}
if (isset($_POST['lowerlabel'])) {$lowerlabel = $_POST['lowerlabel'];}else {$lowerlabel = '';}
if (isset($_POST['middlelabel'])) {$middlelabel = $_POST['middlelabel'];}else {$middlelabel = '';}
if (isset($_POST['upperlabel'])) {$upperlabel = $_POST['upperlabel'];}else {$upperlabel = '';}
$stmt = $db->prepare("INSERT INTO `QuestionnaireQuestions` (`questionnaireID`, `questionnumber`, `questionID`, `question`, `lowerlabel`, `middlelabel`, `upperlabel`) VALUES ($questionnaireID', '$questionnumber', '$questionID', '$question', '$lowerlabel', '$middlelabel', '$upperlabel') WHERE questionnaireID='$questionnaireID';");
if (!$stmt) trigger_error($db->error);
$stmt->execute();
I keep getting the following error though and cant seem to trace what is causing it.
Notice: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '', '3', '1947679104', 'questonofngdfngodfngo', 'lower', 'midddle', 'upper') WHER' at line 1 in /home2/towerroa/public_html/questionnaires/addanotherquestionsubmit.php on line 16 Fatal error: Call to a member function execute() on a non-object in /home2/towerroa/public_html/questionnaires/addanotherquestionsubmit.php on line 17
The table QuestionnaireQuestions looks like this :
id questionnaireID questionnumber questionID question lowerlabel middlelabel upperlabel
You're missing a quote on $questionnaireID:
INSERT INTO `QuestionnaireQuestions` (`questionnaireID`, `questionnumber`, `questionID`, `question`, `lowerlabel`, `middlelabel`, `upperlabel`) VALUES ('$questionnaireID', '$questionnumber', '$questionID', '$question', '$lowerlabel', '$middlelabel', '$upperlabel')
Also remove the WHERE clause.
UPDATE statements can use the WHERE statement to update existing database records based upon a condition. Granted INSERT SELECT statements can contain a WHERE, INSERT statements by themselves do not.
INSERT will not work with the WHERE condition,if only you want to UPDATE the row then you can use WHERE condition and replace this
VALUES ($questionnaireID',......
with
VALUES ('$questionnaireID',
You have missed a single quote and remove ';' from the end also.Now the query will be
$stmt = $db->prepare("INSERT INTO `QuestionnaireQuestions` (`questionnaireID`,
`questionnumber`, `questionID`, `question`, `lowerlabel`,
`middlelabel`, `upperlabel`) VALUES ('$questionnaireID',
'$questionnumber', '$questionID', '$question', '$lowerlabel',
'$middlelabel', '$upperlabel')");
But I must appreciate that you are using PDO statements instead of mysql_* deprecated functions
($questionnaireID'
should be
('$questionnaireID'
but you should really try working with prepared statements

PHP PDO Prepared Statements and Value Binding Gives Invalid Parameter Number Error

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?

Categories