I would like to know if i can prepare one mysqli statement that executes multiple queries:
mysqli->prepare(query1 ...1,2,3 param...; query2...4,5 param...);
or
mysqli->prepare(insert into ...1,2,3 param...; insert into...4,5 param...);
and after all
mysqli->bind_param("sssss", 1, 2, 3, 4, 5);
In that way it make error: Call to a member function bind_param() on a non-object in...
$stmt = $sql->getQueryPrepare("INSERT INTO user (id_user, username, pw, email) VALUES (?,?,?,?); INSERT INTO process (id_user, idp) VALUES (?,?);");
$stmt->bind_param("ssssss",$id, $username, $pw, $email, $id, $idp);
$stmt->execute();
$stmt->close();
A prepared statement can only execute one MySQL query. You can prepare as many statements as you want in different variables:
$stmtUser = $sql->prepare("INSERT INTO user (id_user, username, pw, email) VALUES (?,?,?,?)");
$stmtProc = $sql->prepare("INSERT INTO process (id_user, idp) VALUES (?,?);");
And then execute them later. If you want to ensure that neither one is ever run unless both are able to run, then you need to look into transactions, like Thomas said.
Also, a general tip: "call to member function on a non-object" is the standard error you get when prepare() fails and so $stmt isn't actually a prepared statement object. It usually means you need to look for an error in your prepare() statement rather than anything later.
No, a single call to the mysqli prepare() function cannot prepare multiple queries at once. You can, however, prepare more than one query for execution by using different variables. The documentation for this function is available here.
It also looks like you are trying to setup a transaction, which is a different question than you asked. If that's what you really want to know, then you'll need to provide more information about your database setup and probably more specifics about the use case you are trying to solve.
Related
I would like to know if i can prepare one mysqli statement that executes multiple queries:
mysqli->prepare(query1 ...1,2,3 param...; query2...4,5 param...);
or
mysqli->prepare(insert into ...1,2,3 param...; insert into...4,5 param...);
and after all
mysqli->bind_param("sssss", 1, 2, 3, 4, 5);
In that way it make error: Call to a member function bind_param() on a non-object in...
$stmt = $sql->getQueryPrepare("INSERT INTO user (id_user, username, pw, email) VALUES (?,?,?,?); INSERT INTO process (id_user, idp) VALUES (?,?);");
$stmt->bind_param("ssssss",$id, $username, $pw, $email, $id, $idp);
$stmt->execute();
$stmt->close();
A prepared statement can only execute one MySQL query. You can prepare as many statements as you want in different variables:
$stmtUser = $sql->prepare("INSERT INTO user (id_user, username, pw, email) VALUES (?,?,?,?)");
$stmtProc = $sql->prepare("INSERT INTO process (id_user, idp) VALUES (?,?);");
And then execute them later. If you want to ensure that neither one is ever run unless both are able to run, then you need to look into transactions, like Thomas said.
Also, a general tip: "call to member function on a non-object" is the standard error you get when prepare() fails and so $stmt isn't actually a prepared statement object. It usually means you need to look for an error in your prepare() statement rather than anything later.
No, a single call to the mysqli prepare() function cannot prepare multiple queries at once. You can, however, prepare more than one query for execution by using different variables. The documentation for this function is available here.
It also looks like you are trying to setup a transaction, which is a different question than you asked. If that's what you really want to know, then you'll need to provide more information about your database setup and probably more specifics about the use case you are trying to solve.
I am currently looking at ways to use an API to connect and manage queries securely (SQL injection mitigation), while trying to follow DRY guidelines. I use prepared statements to prevent SQL injections, but I am running into warnings when running the function that is called when an HTTP GET request is received:
Warning: mysqli::bind_param(): Number of variables doesn't match number of parameters in prepared statement...
An then my query fails with:
Error: Commands out of sync; you can't run this command now Errno 2014
A simple google search provides me with this answer:
If you get Commands out of sync; you can't run this command now in your client code, you are calling client functions in the wrong order.
The warnings and error message only happens when there is more than one argument in the array.
My mySQL query function is as follows:
//set properties to values given by constructor params,
//open mysqli connection, etc..
public function query_db_stmt($sql, $param)
{
$stmt = $this->connection->prepare($sql);
for ($i = 1; $i < count($param); ++$i)
{
$stmt->bind_param(($param[0][$i - 1]), $param[$i]);
}
$stmt->execute();
$result = $stmt->get_result();
$stmt->close();
return $result;
} // do other stuff here, like close the sql connection in __destruct()...
And then I create the object and then invoke the query function like so:
$sql = 'SELECT ? FROM user WHERE id=?;';
$result = $mysql_db->query_db_stmt($sql, array('si', '*', $this->args[0]));
I am obviously doing something wrong, as I get these warnings, and a Err number 2014, but I cannot figure out what it is. Any help would be appreciated.
EDIT:
I now understand that I cannot use the column or table name as an prepared statement, but I still have a similar problem when using this code except with a HTTP PUT request:
parse_str(file_get_contents("php://input"), $put_vars);
$sql = 'INSERT INTO user (username, password, email, birth, sex) VALUES (?, ?, ?, ?, ?);';
$mysql_db->query_db_stmt($sql, array('sssss', $put_vars['username'], password_hash($put_vars['password'], PASSWORD_DEFAULT),
$put_vars['email'], $put_vars['birth'], $put_vars['sex']));
Using curl, I run curl -X PUT http://localhost/r.php -d username=foo -d password=boo -d email=test#gmail.com -d birthday=2015-08-13 -d sex=m
And I get the same error 5 times:
Warning: mysqli::bind_param(): Number of variables doesn't match number of parameters in prepared statement...
As before, But no DB Query failed error. Any comments?
The problem is that you are trying to bind the table name in PDO. Table and Column name cannot be replaced in PDO.
You don't need to put the column name in a ? and prepare the statement. Instead just take the values of the statement as params and bind the variables to them.
So, the $sql should be-
$sql = 'SELECT * FROM user WHERE id=?';
Then bind the variables accordingly.
Also, don't use SELECT * in your queries, always specify the column names you want output from.
When using SQL through php mysqli prepared statements, is there any delay on an Insert statement?
For example, in this script:
$sql = "INSERT INTO Records (Name, Data) VALUES (?, ?)";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('ss', $recordName, $data);
$stmt->execute();
echo "INSERT_SUCCESS";
Is the execute() function blocked until the Insert is complete?
If I replace the echo line with a Select query, will it find the newly inserted data or will the data still not be there, as the Insert statement was still not executed when the Select statement was queried.
PHP is a synchronous language. There is no delay. Except for very few cases, the next line won't execute until the previous is finished
This has probably been asked a handful of times already, but I'm having a hard time understanding how to bind an array to a mysqli prepared statement.
What I'm trying to do is query for a list of user id's in a message thread, and then insert into the messages table so the user can be notified of a new message reply.
This is what I've tried:
//now check which users are in the message thread
$stmt2 = $mysqli->prepare("SELECT DISTINCT user_id_2
FROM uc_user_messages
WHERE thread_id = ?");
$stmt2->bind_param("i", $this->thread_id_clean);
$stmt2->bind_result($user_2_id);
$stmt2->execute();
$stmt3 = $mysqli->prepare("
INSERT INTO `users`.`uc_user_messages`(
`id` ,
`message_id` ,
`user_id_2` ,
`read` ,
`thread_id`
)
VALUES (
NULL , ?, ?, ?, ?
);
");
//now insert the message into the user_messages table so the user can be notified of a new message
while ($row = $stmt2->fetch()){
$stmt3->bind_param("iiii", $inserted_id, $user_2_id, $read, $this->thread_id_clean );
$stmt3->execute();
}
What am I doing wrong? I've tried putting the prepared statement inside the loop too, but I keep on getting this error:
Fatal error: Call to a member function bind_param() on a non-object
I've also ran the query manually with test data, so I know it's the loop that's causing the value not to bind correctly.
Edit: I should add that the select query is working fine and that it's the insert query that is causing an error.
Fatal error: Call to a member function bind_param() on a non-object
This means that $stmt2 or $stmt3 is not an object. The prepare() function returns false if there was any problem parsing or validating the query. But false->bind_param() is just not going to work.
This is a very common mistake made by many MySQL developers. The solution is you have to check that prepare() returned success and not false.
Example:
$stmt2 = $mysqli->prepare("...");
if ($stmt2 === false) {
// do something to report $mysqli->error, and return
}
Also see http://php.net/manual/en/mysqli.error.php
once a var has been bound to your prep statement, it stays bound.
That means that cou call bind_param only once (outside of the loop), and then just repeat the two-step-loop "change var values / execute".
php.net: Check section #3 INSERT prepared once, executed multiple times
Also be sure that the quotes you used for db and table names don't interfere with PHPs backtick operator. (In that specific case, you can ommit those quotes.)
You are not checking for the errors. Do it the way explained here: https://stackoverflow.com/a/15447204/285587
Most likely the error is something like "Commands out of sync" one. You have to use store_result() on the first query to avoid that. Strangely, Bill has a perfect answer which is first on google search - you can refer to it for the details.
I only can't get which arrays you are talking about.
I would like to know if i can prepare one mysqli statement that executes multiple queries:
mysqli->prepare(query1 ...1,2,3 param...; query2...4,5 param...);
or
mysqli->prepare(insert into ...1,2,3 param...; insert into...4,5 param...);
and after all
mysqli->bind_param("sssss", 1, 2, 3, 4, 5);
In that way it make error: Call to a member function bind_param() on a non-object in...
$stmt = $sql->getQueryPrepare("INSERT INTO user (id_user, username, pw, email) VALUES (?,?,?,?); INSERT INTO process (id_user, idp) VALUES (?,?);");
$stmt->bind_param("ssssss",$id, $username, $pw, $email, $id, $idp);
$stmt->execute();
$stmt->close();
A prepared statement can only execute one MySQL query. You can prepare as many statements as you want in different variables:
$stmtUser = $sql->prepare("INSERT INTO user (id_user, username, pw, email) VALUES (?,?,?,?)");
$stmtProc = $sql->prepare("INSERT INTO process (id_user, idp) VALUES (?,?);");
And then execute them later. If you want to ensure that neither one is ever run unless both are able to run, then you need to look into transactions, like Thomas said.
Also, a general tip: "call to member function on a non-object" is the standard error you get when prepare() fails and so $stmt isn't actually a prepared statement object. It usually means you need to look for an error in your prepare() statement rather than anything later.
No, a single call to the mysqli prepare() function cannot prepare multiple queries at once. You can, however, prepare more than one query for execution by using different variables. The documentation for this function is available here.
It also looks like you are trying to setup a transaction, which is a different question than you asked. If that's what you really want to know, then you'll need to provide more information about your database setup and probably more specifics about the use case you are trying to solve.