Posting into database using mysqli - php

I am learning php and trying to make the following work:
<?php
require_once("db_connect.php");
// TODO - Check that connection was successful.
$dname = $_POST["dname"];
$daddress = $_POST["daddress"];
$stmt = $mysqli->prepare("INSERT INTO test (dname, daddress) VALUES (?, ?)");
// TODO check that $stmt creation succeeded
// "s" means the database expects a string
$stmt->bind_param("s", $dname, $daddress);
$stmt->execute();
$stmt->close();
$mysqli->close();
?>
It works with just one bind_param but not 2. If $daddress was removed from the code then it posts. The form has 26 posts into database I am doing it with 2 at the moment to keep it minimal.
I get the following error when the form is submitted.
Warning: mysqli_stmt::bind_param() [mysqli-stmt.bind-param]: Number of elements in type definition string doesn't match number of bind variables in /home/mymotorsportco/public_html/entry/actions/entry.php on line 15

As per PHP manual:
types
A string that contains one or more characters which specify the types for the corresponding bind variables
i - corresponding variable has type integer
d - corresponding variable has type double
s - corresponding variable has type string
b - corresponding variable is a blob and will be sent in packets
You have to add types for all the parameters you are binding. So if the second parameter is a string, you have to do
$stmt->bind_param("ss", $dname, $daddress);

You need to pass in the same amount of characters into the first argument, as you have values to inject into your query. For example:
$stmt->bind_param("ss", $dname, $daddress);
Will say that the first param is a string, as well as the second. Additionally, the following will tell the database to expect a string, then an int:
$stmt->bind_param("si", $dname, $daddress);
Big props for using prepared statements, most newbies will throw in variables with absolutely no sanitation. You're on the right track!

You have 2 strings not 1.
$stmt->bind_param("ss", $dname, $daddress);

Related

PDO: Database reports an error: SQLSTATE[HY000]: General error: 2031 [duplicate]

I'm getting this annoying error and although I have an idea of why I'm getting it, I can't for the life of me find a solution to it.
if ($limit) {
$sth->bindValue(':page', $page - 1, PDO::PARAM_INT);
$sth->bindValue(':entries_per_page', $page * $entries_per_page, PDO::PARAM_INT);
}
$sth->execute($criteria);
Query contains placeholders (:placeholder). But to add those LIMIT placeholders, I need to use the manual method (bindValue) because otherwise the engine will turn them into strings.
I'm not getting the Invalid number of parameters error, so all placeholders have been bound correctly (I assume).
Query:
SELECT `articles`.*, `regional_municipalities`.`name` AS `regional_municipality_name`,
`_atc_codes`.`code` AS `atc_code`, `_atc_codes`.`name` AS `substance`
FROM `articles`
LEFT JOIN `_atc_codes`
ON (`_atc_codes`.`id` = `articles`.`atc_code`)
JOIN `regional_municipalities`
ON (`regional_municipalities`.`id` = `articles`.`regional_municipality`)
WHERE TRUE AND `articles`.`strength` = :strength
GROUP BY `articles`.`id`
ORDER BY `articles`.`id`
LIMIT :page, :entries_per_page
All placeholder values reside in $criteria, except for the last two LIMIT, which I manually bind with bindValue().
This same error 2031 can be issued when one bind two values with the same parameter name, like in:
$sth->bindValue(':colour', 'blue');
$sth->bindValue(':colour', 'red');
..so, beware.
You cannot use ->bind* and ->execute($params). Use either or; if you pass parameters to execute(), those will make PDO forget the parameters already bound via ->bind*.
This exception also appears if you try to run a query with placeholders instead of preparing a statment such as
$stmt = $db->query('SELECT * FROM tbl WHERE ID > ?');
instead of
$stmt = $db->prepare('SELECT * FROM tbl WHERE ID > ?');
From the manual:
public bool PDOStatement::execute ([ array $input_parameters ] )
Execute the prepared statement. If the prepared statement included
parameter markers, you must either:
call PDOStatement::bindParam() to bind PHP variables to the parameter markers: bound variables pass their value as input and
receive the output value, if any, of their associated parameter
markers
or pass an array of input-only parameter values
You need to pick a method. You cannot mix both.
It's not exactly an answer, but this error also happens if you try to use a word with a hyphen as placeholders, for example:
$sth->bindValue(':page-1', $page1);
So better use
$sth->bindValue(':page_1', $page1);
This happens if you have mismatching parameters. For example:
$q = $db->prepare("select :a, :b");
$q->execute([":a"=>"a"]);
The exception also happens (at least in MySQL/PDO) when your SQL tries to UPDATE an AUTO_INCREMENT field.

PHP pdo bindParam type management

This is the post form:
$funcname->name= htmlentities($_POST['name']);
$funcname->insert();
this will be the function insert on class funcname which will insert the data to column named name
$this->conn->beginTransaction();
$stmt = $this->conn->prepare("INSERT INTO nameTBL (name) values (:name)";
$stmt->bindParam(':name', $this->name, PDO::PARAM_INT);
if ($stmt->execute()) {
$this->conn->commit(); //This will save your changes
$this->conn->exec('UNLOCK TABLES ' . self::$table_name);
header('Location: ../');
exit();
} else {
$this->conn->rollBack(); //This will undo your changes
$this->conn->exec('UNLOCK TABLES ' . self::$table_name);
header('Location: ../');
exit();
}
Now question is i have set PDO::PARAM_INT which should not allow characters but only integer why i am able to post text to database(table)?
is there any how i can highly restrict the data type on bindParam here.
thanks in advance.
You've got several mistakes in your code.
However, let's go over what the types PDO::PARAM_INT, PDO::PARAM_STR and PDO::PARAM_NULL are telling MySQL to do.
Those values are telling PDO how to treat the input, not to disallow input. If you send text, but the column is int then MySQL will attempt to coerce the data into int. It won't tell you "you entered abcd but expected value was integer". You must do this check on your own before passing data to PDO.
Now onto other problems:
Don't use bindParam. bindParam accepts the value by reference. This is intended for when you invoke stored procedures and variable is supposed to be modified based on procedure's output. Use bindValue. If you tried to do the following with bindParam, it wouldn't work and you'd get an error:
$stmt->bindParam(':my_column', 1, PDO::PARAM_INT); // It fails and yields an error
Don't lock tables. You're already using transactions, no need to lock the table, MySQL handles concurrency and access for you.
Bottom line - perform validation before using PDO for inserting. PDO helps you clean the input based on connection information (among other things). It won't perform validation.

PHP Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: no parameters were bound

I use PDO to execute sql
"INSERT INTO zhushou_cost_uid
(uid,imei,wmac,imsi,channel,supplier,uuid,brand,device_model,os,os_version,app_version,promotion_method,log_source,takeup_date)
VALUES
('863207010118070','863207010118070','02037ff459cb','460025323359694','sc-hjcx_ins_cgq','','�ܟ*c�1�]�y�.���#���h���!�o ��z�!Y�~��t8�KOd�xd]���sm����n%$����H����[?�p���M����','KINGSUN','KINGSUN S6','Android','4.1.2','3.2','','1','2015-11-29 03:21:21')",
PHP code:
$db = $this->getWritableDB();
$stmt = $db->prepare($sql);
$exec = $stmt->execute();
the data of uuid is dirty data, and in our log it is
"uuid":"�ܟ*c�1�]�y�.���#��\u0015�h\u001a���!\u001c�\u0013o �\u0013�z�\u0000!Y�~��t8�KOd�xd]�\u0001��sm\u0016����\u0001n\u0013%$����H����[\u0003?�p���M��\u001a��"
I got the result
SQLSTATE[HY093]: Invalid parameter number: no parameters were bound.
When I try to copy the sql onto the terminator, exiting the mysql login status. I think there is something wrong in uuid. But I can not figure out it. Can anyone help me? Thank you very much!
$stmt = $db->prepare($sql);
Since you're preparing your statement, if there's anything in it that can be interpreted as a question mark or colon, it will be taken as a placeholder and you're expected to then pass values for it in the execute step. Since this is not actually what you're intending, don't prepare the statement if you don't intend to have placeholders in it. Instead:
$db->exec($sql);
Having said that, it's suspicious that you're passing a fully formed SQL query in $sql; perhaps you should be rewriting this whole thing so you do have actual placeholders in your query and are passing the actual values separately to execute.

Why does the mysqli bind function not handle my string correctly?

It took me like a month to figure out how make a session handler function work in PHP. I only had one problem, the bind_param function using i to fetch records instead of s.
$stmt = $mysqli->prepare("SELECT data FROM session WHERE id = ?");
$stmt->bind_param('i', $id);
$stmt->execute();
This $id is a session id with contains numbers and letters like: e5eeire57wjeuewq8w Even if I have no records with this session, this query returns about 8 records in num_rows. So I solved this by putting a s instead of i in bind param.
My question here is, why does bind param treat my string like an integer? Why does it return 8 rows even if I had 0 rows with this id?
There's a comment on the bind_param page that confirms what Jon said in comments
PHP will automatically convert the value behind the scenes to the underlying type corresponding to your binding type string. i.e.:
$var = true;
bind_param('i', $var); // forwarded to Mysql as 1

PDO Prepared Statements: having trouble binding multiple values to query

I am new to PDO and prepared statements and I am having trouble binding multiple values to my query. I have no problem if it is just one while making a SELECT, for example:
SELECT foo FROM table WHERE id=:something // no problem
But multiple, and trying to INSERT I am getting stuck:
Insert INTO mytable (field1, field2) VALUES (:value1, :value2) // No bueno
Have tried a few different ways and read other posts on here but no luck. Below is an example of what I am having trouble with:
$insertSQL = $db->prepare("INSERT INTO voting_poll (ipaddress, choice)
VALUES (':ipaddress', :value)");
$insertSQL->bindParam(':ipaddress', getenv('REMOTE_ADDR'), PDO::PARAM_STR);
$insertSQL->bindParam(':value', $_POST['radio'], PDO::PARAM_STR);
$insertSQL->execute();
I am getting the following error: Invalid parameter number: number of bound variables does not match number of tokens
You don't put quotes around params. Remove the quotes around :ipaddress in your query.
bindParam() must be used with a variable as it binds the parameter to the variable reference. If you want to use a value (for example, the return value from a function like getenv()), use bindValue() instead.

Categories