mysqli: PHP Fatal error: Call to a member function fetch_array() - php

I am having some trouble with prepared statements. Basically, this query is returning no rows, even though I know for a fact that this query should return multiple rows. I thought this was just a problem due to SQL injections, but maybe I'm doing something else wrong here, I don't know. If I take out the check for how many rows there are, I get an error:
PHP Fatal error: Call to a member function fetch_array()
Any help would be appreciated!
$stmt = $mysqli->prepare("SELECT sid from SDS WHERE uid=? AND dst=?");
$stmt->bind_param('ss',$username,$structureType);
$stmt->execute();
$stmt->bind_result($results);
$stmt->fetch();
if ($results) {
if($results->num_rows == 0) {
print("No results here.");
return 0;
}
$recordnames = array();
while ($next_row = $results->fetch_array()) {
$recordnames[] = $next_row['sid'];
}
return $recordnames;
}

When you use $stmt->bind_result($result); you are binding the sid from the database to the variable $results. So you cannot perform operations like :
if($results->num_rows == 0) { //... }
or
$results->fetch_array();
This is how I would do it :
<?php
$stmt = $mysqli->prepare("SELECT sid from SDS WHERE uid=? AND dst=?");
$stmt->bind_param('ss', $username, $structureType);
$stmt->execute();
$stmt->bind_result($sid);
$stmt->store_result();
if ($stmt->num_rows == 0)
{
print("No results here.");
$stmt->close();
return 0;
}
else
{
$recordnames = array();
while($stmt->fetch())
{
$recordnames[] = $sid;
}
return $recordnames;
}
?>
This way uses a different logic, check if the row count is 0, if so display "No results here", if not put results into the array.

Related

Returning array and num rows mysqli prepared

I'm a bit new to the mysqli prepared statement and I would like to use fetch_array to return the results AND also return num_rows as an array value.
I have something like this
function getCategories($dbh, $catId)
{
$data = array();
$s = "SELECT id, title FROM categories WHERE parent_id = ?";
if ($stmt = mysqli_prepare($dbh, $s)) {
mysqli_stmt_bind_param($stmt, "i", $catId);
mysqli_stmt_execute($stmt);
if (mysqli_stmt_errno($stmt)) {
exit(mysqli_stmt_error($stmt));
}
mysqli_stmt_store_result($stmt);
$count = mysqli_stmt_num_rows($stmt)) {
if ($count) {
$data['count'] = $count;
$result = mysqli_stmt_get_result($stmt);
while ($r = mysqli_fetch_assoc($result)) {
$data[] = $r;
}
}
return $data;
} else {
exit(mysqli_error($dbh));
}
}
It seems that I cannot use mysqli_stmt_store_result and mysqli_stmt_get_result().
The store_result function seems to give a boolean and then I get this error: "mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given"
Hope this makes sense. Any help would be really appreciated.
Updated:
function getCategories($dbh, $catId)
{
$data = array();
$s = "SELECT id, title FROM categories WHERE parent_id = ?";
if ($stmt = mysqli_prepare($dbh, $s)) {
mysqli_stmt_bind_param($stmt, "i", $catId);
mysqli_stmt_execute($stmt);
if (mysqli_stmt_errno($stmt)) {
exit(mysqli_stmt_error($stmt));
}
$result = mysqli_stmt_get_result($stmt);
$data['count'] = $result->num_rows;
while ($r = mysqli_fetch_assoc($result)) {
$data[] = $r;
}
return $data;
} else {
exit(mysqli_error($dbh));
}
}
According to the PHP docs, mysqli_stmt_get_result returns FALSE on error:
Returns a resultset for successful SELECT queries, or FALSE for other DML queries or on failure. The mysqli_errno() function can be used to distinguish between the two types of failure.
You're then passing that into mysqli_fetch_assoc which complains because you're giving it a bool instead of the resultset it expects.
Do a little more erroring checking at that point and you'll be fine. There's probably something wrong with your SQL query. Call mysqli_errorno to determine if there's an error, as the docs state above.
EDIT:
Use the mysqli_error function to get a description of the mysql error. It would be best to use this everywhere you're checking for failure as having an error message will make debugging much easier than simply failing silently.

Retrieving data from database using prepared statement

I'm having problem retrieving my data from my database. Here's my code:
function login($email, $password) {
$stmt = $this->conn->prepare("SELECT id FROM lms_admin_users WHERE email=?");
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows == 1) {
while ($stmt->fetch()) {
// echo data from table like $data["name"]; <----
}
}
else {
echo "Failed";
}
}
What I want to know is the equivalent of while($data=mysqli_fetch_assoc($result)) to replace my existing code (in OOP way) while ($stmt->fetch()) and make it fetch the datas using $data["name"]
You need to tell PHP in which variable(s) to store the result. There are two ways to do this:
with bind_result, and then fetch on the statement object, or
with get_result, and then fetch_assoc (or other fetch_* variant) on the result object
1. bind_result
With this solution you bind variable(s) to the SELECT list, and while looping with fetch PHP will put the new data in those variable(s):
$stmt = $this->conn->prepare("SELECT id FROM lms_admin_users WHERE email=?");
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($id, $name); // <- Add; #args = #cols in SELECT
if($stmt->num_rows == 1) {
while ($stmt->fetch()) {
echo $id, $name; // <-- then you can do this.
}
}
2. get_result
Instead of bind_result you can use get_result, which will give a result object which you can fetch each row from as an associative array:
//...
// $stmt->store_result(); // <- Remove: does not work together with next statement
$result = $stmt->get_result(); // <--- add this instead
if($result->num_rows == 1) { // <--- change to $result->...!
while ($data = $result->fetch_assoc()) {
echo $data['id'], $data['name']; // <--- available in $data
}
}

correct way to check if user is found in mysql table

The function should return the id of the found user or return false if not found.
Currently I am using bind result and fetch to check if a user is found in an mysql table:
public function getUserIDByName($UserName) {
$uid = "";
$i=0;
if($stmt = $this->mysqlserver->prepare("SELECT uid FROM user WHERE name=?")){
$stmt->bind_param("s", $UserName);
$stmt->execute();
$stmt->bind_result($uid);
while($stmt->fetch()){
$i++;
}
$stmt->close();
}
if($i==0){
return false;
}else{
return $uid;
}
}
This works, but I assume that there is a proper way to do this without a counter in the fetch loop. I can not use get_result as mysqlnd is not available.
Simple use num_rows to check your query return result or not
function getUserIDByName($UserName) {
if ($stmt = $this->mysqlserver->prepare("SELECT uid FROM user WHERE name=?")) {
$stmt->bind_param("s", $UserName);
$stmt->execute();
$row_cnt = $stmt->num_rows;
if ($row_cnt == 1) {
$stmt->bind_result($uid);
while ($stmt->fetch()) {
return $uid;
}
} else {
return false;
}
}
}
Use this instead
public function getUserIDByName($UserName)
{
$uid = '';
$response = false;
$stmt = $this->mysqlserver->prepare("SELECT uid FROM user WHERE name=?");
$stmt->bind_param("s", $UserName);
$stmt->execute();
$stmt->bind_result($uid);
if ($stmt->fetch()) {
$response = $uid;
}
$stmt->close();
return $response;
}
EDIT: just realized you're using mysqli and not pdo. Ill leave this here if you want to use PDO in the feature I guess.
This is how I would do it. You could change rowcount() > 0 to rowcount() === 1 if you want to guarantee only 1 user is found.
public function getUserIDByName($UserName)
{
$stmt = $this->mysqlserver->prepare("SELECT uid FROM user WHERE name = :name");
// bind :name to the username
$stmt->bindParam(":name", $UserName);
// execute the query
$stmt->execute();
// check the rowcount
if ($stmt->rowcount() > 0) {
// fetch the results as a associative array
return $stmt->fetch(PDO::FETCH_ASSOC);
}
// return false because rowcount wasn't bigger than 0
return false;
}

MySQLI prepared failing return results

I have tried thousand of examples but non working, I try to get results on specific row where id= .
My code :
if ($stmt = $func->mysqli->prepare("SELECT * FROM monthlypaymentsrequestlist WHERE id = ?")) {
$stmt->bind_param('s', $user['userid']);
// Execute the prepared query.
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows > 0) {
while ($rows = $stmt->fetch_assoc()) {
echo $row['id'];
}
}
}
The error i get :
Fatal error: Call to undefined method mysqli_stmt::fetch_assoc() in
How i do it properly ?
fetch_assoc() is a function of a mysqli_result, not the $stmt Resource you're trying to use. You need to assign it to the return of execute():
if($stmt = $func->mysqli->prepare("SELECT * FROM monthlypaymentsrequestlist WHERE id = ?"))
{
$stmt->bind_param('s', $user['userid']);
// Execute the prepared query.
$result = $stmt->execute();
$stmt->store_result();
if($stmt->num_rows > 0)
{
while($rows = $result->fetch_assoc())
{
echo $row['id'];
}
}
}
fetch_assoc is a method of the mysqli_result class, not the mysqli_stmt class.

Count left attempts rows

I have this MYSQL Table :
id | action
A6bIMWP1rQ changedusername
A6bIMWP1rQ changedusername
Now how i make this php function to count if more then 5 times changedusername exsit, it will return false?
i have tryed:
function checkIfOverFive($id,$mysqli) {
global $func; //The database connection
if ($stmt = $mysqli->prepare("SELECT action FROM userchange_attemps WHERE user_id = ?")) {
$stmt->bind_param('i', $id);
// Execute the prepared query.
$stmt->execute();
$stmt->store_result();
// If there has been more than 5 failed logins
if($stmt->num_rows > 5) {
return true;
}else{
return false;
}
}
}
And how with php i determine how much left attemps upto 5 ?
Lets say now in my table theres 2 rows, and left 3 , how i return that value to the user ?
Thanks.
Use mysql COUNT
function checkIfOverFive($id,$mysqli) {
global $func; //The database connection
if ($stmt = $mysqli->prepare("SELECT COUNT(id) as count FROM userchange_attemps WHERE user_id = ? AND action = 'changedusername'")) {
$stmt->bind_param('i', $id);
// Execute the prepared query.
$stmt->execute();
$stmt->store_result();
$row = $stmt->fetch_assoc();
if($row['count'] > 5) {
//do something
} else {
//do something else
}
}
}
How about...
SELECT COUNT(action)
FROM userchange_attemps
WHERE action = 'changedusername' AND user_id= ?

Categories