I have a issue with my prepared statement, I have searched through stack for the answer and tried many off them them to no avail, I have check the insert statement which is correct, I have also tried using the statement as a regular statement which seems to work,
The error I get is as below
Fatal error:call to function bind_param()on a non object in ** on line 23
When I use a normal query on the first query the second does not show the error
The code is
public function reg_user($name,$username,$password,$email){
$password = password_hash($password);
$stmt = $this->db->prepare("SELECT uid FROM users WHERE uname= ? OR uemail = ?");
$stmt->bind_param("ss", $username,$email);
$stmt->execute();
$count_row = $stmt->num_rows;
if($count_row == 0){
$stmt = $this->db->prepare("INSERT INTO users (uname,upass,fullname,uemail) VALUES(?,?,?,?)");
$stmt->bind_param("ssss", $username,$password,$name,$email); //line 23
$return = $stmt->execute();
return $return;
} else{
return false;
}
}
Add these two lines of code after the first $stmt->execute
$result = $stmt->get_result();
$count_row = $result->num_rows;
The reason why your code fails is because you are trying to get the number of rows from a Prepared Statement object instead of a Result
Related
I have one simple function for delete account from my database. I have written it like below
public function removeAccount($email) {
$response = array('code' => 0, 'error' => false);
$stmt = $this->conn->prepare("SELECT id FROM user WHERE email = ?");
$stmt->bind_param("s", $email);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows) {
$user = $result->fetch_assoc();
$id = $user['id'];
$stmt->close();
$stmt = $this->conn->prepare("DELETE FROM number_list WHERE user_id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->close();
$stmt = $this->conn->prepare("DELETE FROM number_status WHERE user_id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->close();
$stmt = $this->conn->prepare("INSERT INTO old_user(email,serial,premium) SELECT email, device_id, membership FROM user WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->close();
$stmt = $this->conn->prepare("DELETE FROM user WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->close();
if ($stmt->affected_rows) {
$response["code"] = 1;
}
}
return $response;
}
Its giving me warning in below line
if ($stmt->affected_rows) {
I have searched way for solve it but does not getting idea whats wrong and what can fix it. Please check and let me know if someone can have idea about it. Thanks a lot.
$stmt = $this->conn->prepare("DELETE FROM user WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
if($stmt->affected_rows > 0) { $response["code"] = 1; }
$stmt->close();
In this case, we checked to see if any rows got updated. For reference, here's the usage for mysqli::$affected_rows return values.
-1 - query returned an error; redundant if there is already error handling for execute()
0 - no records updated on UPDATE, no rows matched the WHERE clause or no query has been executed
Greater than 0 - returns number of rows affected; comparable to mysqli_result::$num_rows for SELECT
You're trying to get the number of affected rows from a closed statement.
Instead of
$stmt->execute();
$stmt->close();
if ($stmt->affected_rows) {
$response["code"] = 1;
}
Use
$stmt->execute();
$num_affected_rows = $stmt->affected_rows;
$stmt->close();
if ($num_affected_rows) {
$response["code"] = 1;
}
There are many reasons for this error, but the one I had today was one I have not found documented anywhere.
I had two (2) copies of same virtual machine running and they were both competing in some way that I do not understand well enough to explain, but going into VirtualBox and shutting one of them off solved the problem.
I know this an obscure scenario, but if anyone else runs across the same I hope my answer stops them from wasting time on it like I did.
This question already has answers here:
mysqli_stmt::bind_result(): Number of bind variables doesn't match number of fields in prepared statement
(2 answers)
Closed 1 year ago.
Iam getting this error
[07-Sep-2017 11:48:47 UTC] PHP Warning: mysqli_stmt::bind_result():
Number of bind variables doesn't match number of fields in prepared
statement
$stmt = $con->prepare("SELECT * FROM table where Id =?");
$stmt->bind_param("s", $_POST['Id']);
$stmt->execute();
$result = $stmt-> bind_result($Id);
$numRows = $result->num_rows;
if($numRows > 0) {
if($row = $result->fetch_assoc())
{
$Taxname=$row['TaxName'];
$Tid=$row['Id'];
}}
You need to alter your query. Instead of * you need to instead opt for picking out the data you actually want from the database.
For example, if the table table has columns Id,TaxName then you would execute like so:
<?php
$sqlData = array();
$stmt = $con->prepare("SELECT Id,TaxName FROM table where Id =?");
$stmt->bind_param("i", $_POST['Id']); //id is an integer? this should be i instead of s
$stmt->execute();
$stmt->store_result(); //store the result, you missed this
$stmt-> bind_result($Id,$TaxName); //bind_result grabs the results and stores in a variable
$numRows = $stmt->num_rows; //see the correction I made here
if($numRows >0){
while ($stmt->fetch()) { //propper way of looping thru the result set
$sqlData [] = array($Id,$TaxName);
//assoc array would look like:
//$sqlData [] = array("Id" =>$Id,"TaxName" => $TaxName);
}
}
$stmt->close(); //close the connection
?>
Then you would have an array of results that you can use after you've finished with mysqli queries.
Hope this helps you understand it a bit more.
$stmt = $con->prepare("SELECT Id,TaxName FROM table where Id =?");
$stmt->bind_param("s", $_POST['Id']);
$stmt->execute();
$result = $stmt-> bind_result($Id,$TaxName);
$stmt->store_result();
$numRows = $stmt->num_rows;
if($numRows > 0) {
while( $result->fetch_assoc())
{
$newid = $Id;
$newtaxname= $TaxName;
}
print_r($newid)."<br>";
print_r($newtaxname);
}
This code will give you the answer without any warnings.
Reference : http://php.net/manual/en/mysqli-stmt.bind-result.php
mysqli_stmt::bind_result — Binds variables to a prepared statement for
result storage
I'm currently going thorough a site and replacing all the functions which used to return mysql_fectch_array() results, which are put into while loops elsewhere. I'm trying to make them return the same data in the same format but by using mysqli prepared statements output. I have been successful with the code below in producing the same formatted output for single row results.
public function get_email_settings(){
$stmt = $this->cn->stmt_init();
$stmt->prepare("SELECT * FROM email_setting WHERE user_id = ? LIMIT 1");
$stmt->bind_param("i", $this->user);
$stmt->execute();
$stmt->bind_result(
$row['email_id'],
$row['user_id'],
$row['news'],
$row['new_message'],
$row['new_friend'],
$row['rule_assent'],
$row['agreement_ready'],
$row['agreement_all_assent'],
$row['time_cap'],
$row['donations']
);
$stmt->store_result();
$stmt->fetch();
$stmt->close();
return $row;
}
But how can I get this code to work when it returns more than one row? I want it to be produce the same result as if I had written:
return mysql_fetch_array($result);
Is it possible?
Consider the following adjustment, passing query results into an associative array:
public function get_email_settings(){
$stmt = $this->cn->stmt_init();
$stmt->prepare("SELECT email_id, user_id, news, new_message,
new_friend, rule_assent, agreement_ready,
agreement_all_assent, time_cap, donations
FROM email_setting
WHERE user_id = ? ");
$stmt->bind_param("i", $this->user);
$stmt->execute();
// CREATE RETURN ARRAY
$row = [];
// OBTAIN QUERY RESULTS
$result = $stmt->get_result();
// ITERATE THROUGH RESULT ROWS INTO RETURN ARRAY
while ($data = $stmt->fetch_assoc()) {
$row[] = $data;
}
$stmt->close();
return $row;
}
You will notice I explicitly select the query's fields to avoid an indeterminate loop through query results.
Ok I have managed to get it to work without using get_result()
This is how I did it with alot of help from Parfait and Example of how to use bind_result vs get_result
function saved_rules($user){
$stmt = $this->cn->stmt_init();
$stmt->prepare("SELECT R.rule_id, R.rule_title
FROM Savedrules S
LEFT JOIN Rule R
ON S.saved_rule_id = R.rule_id
WHERE S.saved_user_id = ?");
$stmt->bind_param("i", $user);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($id, $rule_title);
while ($stmt->fetch()) {
$result[] = Array("rule_id"=>$id,"rule_title"=>$rule_title);
}
$stmt->free_result();
$stmt->close();
return $result;
}
Its not exactly the same output as using a mysql_fetch_array() so where it is used I have to change the loop to:
foreach($saved_rules AS $row){}
from
while ($row = mysql_fetch_array($saved_rules){}
trying to convert all my old mysql_* operations into new and, from what i've heard, improved PDO, but this query wont seem to run successfully, I am trying to select all from the table PEOPLE where the username = $username (which has previously been declared $username = $_SESSION['username'];)
$query = "SELECT * FROM people WHERE username=?";
$stmt = $conn->prepare($query);
$stmt->bindParam(1, $username);
$stmt->execute();
$num_rows = $stmt->fetchColumn();
if ($num_rows == 1) {
// ...
}
THE WORKING CODE IS:
$query = "SELECT * FROM people
WHERE username=?";
$stmt = $conn->prepare($query);
$stmt->bindParam(1, $username);
$stmt->execute();
$num_rows = $stmt->fetchColumn();
$user = $stmt->fetchObject();
if ($user) {
//do something
}
$stmt->fetchColumn does not fetch the number of rows; in this case it will fetch the first column from the first row of the result set. Since that will not be equal to 1 generally your test will fail.
In this case there is also no real need to count the number of returned rows because you are expecting either one or zero (if the username does not exist). So you can simply do:
$stmt->execute();
$user = $stmt->fetchObject();
if (!$user) {
// not found
}
else {
echo "User $user->username found!";
}
The if(!$user) test works because if there is no row to fetch $user will be false (see the documentation for fetchObject).
$query = "SELECT * FROM people WHERE username = :username";
$stmt = $conn->prepare($query);
$stmt->bindParam(':username', $username);
$stmt->execute();
while ($row = $stmt->fetchObject()) {
// do stuff
}
Use PDOStatement::rowCount as the num_rows and PDOStatement::fetch(PDO::FETCH_ASSOC) as fetch_assoc equivalent.
You want
if ($stmt->num_rows == 1) {
instead.
I am receiving a fatal error in my php/mysqli code which states that on line 46:
Fatal error: Call to undefined method mysqli_stmt::fetch_assoc() in ...
I just want to know how can I remove this fatal error?
The line of code it is pointing at is here:
$row = $stmt->fetch_assoc();
ORIGINAL CODE:
$query = "SELECT Username, Email FROM User WHERE User = ?";
// prepare query
$stmt=$mysqli->prepare($query);
// You only need to call bind_param once
$stmt->bind_param("s",$user);
// execute query
$stmt->execute();
// get result and assign variables (prefix with db)
$stmt->bind_result($dbUser, $dbEmail);
//get number of rows
$stmt->store_result();
$numrows = $stmt->num_rows();
if ($numrows == 1){
$row = $stmt->fetch_assoc();
$dbemail = $row['Email'];
}
UPDATED CODE:
$query = "SELECT Username, Email FROM User WHERE User = ?";
// prepare query
$stmt=$mysqli->prepare($query);
// You only need to call bind_param once
$stmt->bind_param("s",$user);
// execute query
$stmt->execute();
// get result and assign variables (prefix with db)
$stmt->bind_result($dbUser, $dbEmail);
//get number of rows
$stmt->store_result();
$numrows = $stmt->num_rows();
if ($numrows == 1){
$row = $stmt->fetch_assoc();
$dbemail = $row['Email'];
}
The variable $stmt is of type mysqli_stmt, not mysqli_result. The mysqli_stmt class doesn't have a method "fetch_assoc()" defined for it.
You can get a mysqli_result object from your mysqli_stmt object by calling its get_result() method. For this you need the mysqlInd driver installed!
$result = $stmt->get_result();
row = $result->fetch_assoc();
If you don't have the driver installed you can fetch your results like this:
$stmt->bind_result($dbUser, $dbEmail);
while ($stmt->fetch()) {
printf("%s %s\n", $dbUser, $dbEmail);
}
So your code should become:
$query = "SELECT Username, Email FROM User WHERE User = ?";
// prepare query
$stmt=$mysqli->prepare($query);
// You only need to call bind_param once
$stmt->bind_param("s",$user);
// execute query
$stmt->execute();
// bind variables to result
$stmt->bind_result($dbUser, $dbEmail);
//fetch the first result row, this pumps the result values in the bound variables
if($stmt->fetch()){
echo 'result is ' . dbEmail;
}
Change,
$stmt->store_result();
to
$result = $stmt->store_result();
And
Change,
$row = $stmt->fetch_assoc();
to
$row = $result->fetch_assoc();
You have missed this step
$stmt = $mysqli->prepare("SELECT id, label FROM test WHERE id = 1");
$stmt->execute();
$res = $stmt->get_result(); // you have missed this step
$row = $res->fetch_assoc();
I realized that this code was provided as an answer somewhere on stackoverflow:
//get number of rows
$stmt->store_result();
$numrows = $stmt->num_rows();
I tried it to get the number of rows but realized that i didnt need the line $stmt->store_result();, and it didn't get me my number. I used this:
$result = $stmt->get_result();
$num_of_rows = $result->num_rows;
......
$row = $result->fetch_assoc();
$sample = $row['sample'];
It's best to use mysqlnd as Asciiom pointed out. But if you're in a weird situation where you are not allowed to install mysqlnd, it is still possible to get your data into an associative array without it. Try using the code in this answer
Mysqli - Bind results to an Array