PHP PDO: Call to a member function fetch() on boolean - php

So I'm currently trying to do a PDO SELECT Request, but when executing and fetching the extracted data, this error shows up:
1 - Fatal error: Uncaught Error: Call to a member function fetch() on boolean in C:\wamp64\www\NewKali\includes\user.inc.php on line 53
2 - Error: Call to a member function fetch() on boolean in C:\wamp64\www\NewKali\includes\user.inc.php on line 53
This is where I call the function:
include 'includes/user.inc.php';
$userOBJ = new User;
if($userOBJ->isAdmin($_SESSION['session_u-name'])){
AdminControl();
}
Code:
public function isAdmin($user){
$userToGet = $user;
$stmt = $this->Connect()->prepare("SELECT * FROM user_secure WHERE username_db=?");
$query1 = $stmt->execute([$userToGet]);
if(!$query1)
{
die("Execute query error, because: ". print_r($this->Connect()->errorInfo(),true) );
}else{
foreach ($query1->fetch() as $row) {
if($row['admin_db'] == 1){
return true;
} else {
return false;
}
}
}
}
The first error says that I'm not handling the PDO errors, which I think that I'm already handling any PDO error in my code, but somehow still gets detected as I'm not doing so... (Correct me if wrong)
Second error states that calling PDO->fetch() is returning a boolean, but I'm requesting data, so it's not able to continue with the following code...
I don't get why this is showing... The "username_db" var in the query is the same as the one that I have in my DB.
In the same file as the function above, I have this next function and when called, it does fine
public function RegisterUser($user, $pwd, $mail){
$u_Insert = $user;
$p_Insert = $pwd;
$m_Insert = $mail;
$stmt = $this->Connect()->prepare("INSERT INTO user_secure(username_db, password_db) VALUES (?,?)");
$query1 = $stmt->execute([$u_Insert, $p_Insert]);
$stmt = $this->Connect()->prepare("INSERT INTO user_info(mail_db) VALUES (?)");
$query2 = $stmt->execute([$m_Insert]);
if($query2 && $query1){
return true;
} else {
return false;
}
}
Is there something that I'm missing?
I have already checked this thread but I'm still in the exact position...
Thank you for your time
(I'm still learning PDO, sorry if my code isn't clean)

This line here is one of the reasons. execute returns true or false indicating if the query succeeded or failed.
$query1 = $stmt->execute([$userToGet]);
In a sense, $query1 is a boolean.
Now in these lines, you are trying to access the fetch method from $query1 which is a boolean.
foreach ($query1->fetch() as $row) {
if($row['admin_db'] == 1){
return true;
} else {
return false;
}
}
To get the row, you need to write it like this:
$results = $stmt->fetch();
or in your case:
foreach ( $stmt->fetch() as $row) {
if($row['admin_db'] == 1){
return true;
} else {
return false;
}
}

Related

Notice: Trying to access array offset on value of type bool in C:\xampp\htdocs\twitter\core\classes\follow.php on line 25

Everything seems to be working good but i am getting an error:
I checked for typos in my follow.php and profile.php and even retyped the major part of the code but was not able to figure out the problem.
This is my line 25 of follow.php
if($data['reciever'] == $profileID)
Here is my follow.php
<?php
class Follow extends User
{
function __construct($pdo)
{
$this->pdo = $pdo;
}
public function checkFollow($followerID, $user_id)
{
$stmt = $this->pdo->prepare("SELECT * FROM `follow` WHERE `sender` = :user_id AND `reciever` = :followerID");
$stmt->bindParam(":user_id", $user_id, PDO::PARAM_INT);
$stmt->bindParam(":followerID", $followerID, PDO::PARAM_INT);
$stmt->execute();
return $stmt->fetch(PDO::FETCH_ASSOC);
}
public function followBtn($profileID, $user_id)
{
$data = $this->checkFollow($profileID, $user_id);
if($this->loggedIn() === true)
{
if($profileID != $user_id)
{
if($data['reciever'] == $profileID)
{
//Following Button
echo "<button class='f-btn following-btn follow-btn' data-follow='".$profileID."'>Following</button>";
}
else
{
//follow button
echo "<button class='f-btn following-btn follow-btn' data-follow='".$profileID."'><i class='fa fa-user-plus'></i>Follow</button>";
}
}
else
{
//edit button
echo "<button class='f-btn' onclick=location.href='profileEdit.php'>Edit Profile</button>";
}
}
else
{
echo "<button class='f-btn' onclick=location.href='index.php'><i class='fa fa-user-plus'></i>Follow</button>";
}
}
}
?>
The error states:
Trying to access array offset on value of type bool
and this is happening on line 25 of follow.php
So, On looking at line 25 of follow.php
if($data['reciever'] == $profileID)
According to the error, we are trying to access an element in an array but the object is actually a boolean. So, $data must be a boolean. Looking a few lines up, on line 20 there is:
$data = $this->checkFollow($profileID, $user_id);
So $data is being set by the return value of checkFollow. checkFollow must be giving us a boolean. Looking at checkFollow we see it returns this:
return $stmt->fetch(PDO::FETCH_ASSOC);
the boolean must be coming from $stmt->fetch. Let's look at the documentation for this method, which states:
The return value of this function on success depends on the fetch
type. In all cases, FALSE is returned on failure.
My DB:
So that's the source of the error. Why is fetch returning FALSE though?Maybe query is not returning any results. Perhaps there are no rows in the database that match the given parameters.But I don't know how to implement it as i am just beginning in PHP.If someone could show me the syntax for better clarification it would be highly appreciated.!
Thank you!

Call to a member function fetchAll() on boolean

I have the following problem.
This error persisting in accompanying me
Fatal error: Uncaught Error: Call to a member function fetchAll() on boolean in C:\xampp\htdocs\certificado\functions.php:49 Stack trace: #0 C:\xampp\htdocs\certificado\index.php(11): get_info_from_email('amanda_pandoka#...') #1 {main} thrown in C:\xampp\htdocs\certificado\functions.php on line 49
In the code below I can not understand the error. Can someone help me?
function connect() {
$socket = new PDO('mysql:host=' . #$host . ';dbname=' . #$nomedobancodedados,
#$usuario, #$senha);
$socket->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
return $socket;
}
function get_info_from_email($email) {
if (!$email)
return false;
global $db;
$sql = "
SELECT
id,
name,
email,
type,
data,
file
FROM
attendee
WHERE 1=1
AND email = '{$email}'
";
if ($info = $db->query($sql))
return false;
if ($info = $info->fetchAll())
return false;
return $info;
}
if ($info = $db->query($sql))
return false;
This says: if the result of $db->query($sql) can be stored in $info and is not something like false, null or an empty string or array, stop now and return false. So basically, if your query executes successfully and properly returns a PDOStatement with results in it, your function stops here.
if ($info = $info->fetchAll())
return false;
This is where you're getting the error. The fact that this code is reached at all means that the query failed to execute (otherwise, it would have returned false earlier). So basically, you're calling fetchAll() on false. Try to see what the error is here (do a print_r($db->errorInfo()); before this if-statement)
By the way, this if-statement will also cause your function to return false if the fetchAll() call was successful, which is probably not what you want. Additionally, by using $db->query() directly with the email address provided in the function call, you're leaving your code open to possible SQL injection attacks. As a rule, never trust any variable if you don't have 100% control over what's in it. You should use a prepared statement instead.
As another rule, always use curly braces on code blocks (if/elseif/else, for/foreach/while/do, try/catch/finally), because then you don't need to think about them anymore if you someday decide that the code block should do two things instead of one, and it's easier to debug code if you can visually see exactly what your code is trying to do.
This code (not tested) should work the way you want:
function get_info_from_email($email) {
if (!$email) {
return false;
}
global $db;
$stmt = $db->prepare("
SELECT
id,
name,
email,
type,
data,
file
FROM
attendee
WHERE 1=1
AND email = :email
");
// return false if the query cannot be executed
if (!$stmt->execute(array(':email' => $email))) {
return false;
}
// return false if there was an **error** retrieving the query results
if (($info = $stmt->fetchAll()) === false) {
return false;
}
return $info;
}
Continue like this
function get_info_from_email($email) {
if (!$email) {
return false;
}
global $db;
$sql = $db->prepare("
SELECT
id,
name,
email,
type,
data,
file
FROM
attendee
WHERE 1=1
AND email = :email
");
print_r($db->errorInfo());
// return false if the query cannot be executed
if (!$sql->execute(array(':email' => $info))) {
return false;
}
// return false if there was an **error** retrieving the query results
if (($info = $sql->fetchAll()) === false) {
return false;
}
return $info;
}

Using SQL in a function

I'm trying to create a function in PHP that connects to SQL with the global $conn, and another which authenticates the user. However, referencing the SQL connection function in the second function isn't working.
Error:
Fatal error: Call to a member function query() on a non-object in /[...]/functions.php on line [see below]
SQLinfo.php contains valid database information, in the form of constants SQLurl, SQLuser, SQLpass & SQLdatabase.
Code:
function SQLconnect(){
require 'SQLinfo.php';
global $conn;
$conn = new mysqli(SQLurl,SQLuser,SQLpass,SQLdatabase);
if($conn->connect_error){
return $conn->connect_error;
}else{
return True;
}
}
function isauthenticated($username,$token){
if(empty($username) || empty($token)){
return False;
}else{
SQLconnect();
//error line:
$result = $conn->query("SELECT * FROM `userdata` WHERE `username` = '".$username."' AND `lastid` = '".$token."'");
if($result->num_rows == 1){
return True;
}else{
return False;
}
$result->free;
}
}
I tried looking at this answer, however since the mysql extension is deprecated and the global has been defined I couldn't figure it out. I'd appreciate any help.

PHP PDO CRUD class Call to a member function rowCount() on a non-object

I'm just getting started using PDO to move away from mysqli but hit a problem. I'm following a tutorial and I want to return an array from the database but I get the following error:
Fatal error: Call to a member function rowCount() on a non-object in C:\xampp\htdocs\phptuts\crud\core\managedb.class.php on line 27
Here is my managedb.php class:
<?php
class ManageDatabase
{
public $link;
function __construct()
{
include_once('database.class.php');
$conn = new database;
$this->link = $conn->connect();
return $this->link;
}
function getData($table_name, $id=null)
{
if(isset($id))
{
$query = $this->link->query("SELECT * FROM $table_name WHERE id = '$id' ORDER BY id ASC");
}
else
{
$query = $this->link->query("SELECT * FROM $table_name ORDER BY id ASC");
}
$rowCount = $query->rowCount();
if($rowCount >= 1)
{
$result = $query->fetchAll();
}
else
{
$result = 0;
}
return $result;
}
}
Then I'm simply using the following code to try and get a response:
<?php
include_once('../core/managedb.class.php');
$init = new ManageDatabase;
$table_name = 'users';
$data = $init->getData($table_name);
print_r($data);
This is when I get the error, Any ideas?
I'd var_dump($query) before the $rowCount = $query->rowCount(); line to see what it actually is, because apparently it's not an object. I'm guessing it's either NULL or empty because the whole $this-link->query(<sql statement>); didn't return what you expected
A couple of things to check out:
From the PHP manual:
PDO::query() returns a PDOStatement object, or FALSE on failure.
You'll want to test if the query succeed and if not, why. You can check the error using PDO's errorInfo function:
if ($query == false)
{
print_r($this->link->errorInfo());
exit();
}
Another thing to note is that rowCount() in PDO returns the affected rows from a INSERT / UPDATE / DELETE type statement. For a SELECT you may get a row count, or you may not. The manual suggests a separate query to find the number of rows, but in your instance it might be easier testing if you get anything back from fetchAll():
$result = $query->fetchAll();
if (!empty($result))
{
return $result;
}
else
{
return 0;
}

PHP: How can I check for errors during a mysqli commit?

I am inserting a lot of records using mysqli commit statement, using this code from http://www.php.net/manual/en/mysqli.commit.php#88857. I then check affected rows using:
$mysqli->affected_rows
but even though all records have been inserted, I get zero affected rows.
How can I check when commit failed and retrieve the error?
Thank you
You could do something like this:
mysqli_autocommit($dbconn, FALSE);
$errors = array();
if (!$mysqli->query(/* some SQL query */)) {
$errors[] = $mysqli->error;
}
// ... more queries like the above
if(count($errors) === 0) {
$mysqli->commit()
} else {
$mysqli->rollback();
print_r($errors);
}
When a query goes wrong, it will add the error to the $errors array, so you will know what went wrong. You could also add keys with identifiers for the queries, so you know which query went wrong.
For better handling, you could write a UnitOfWork class for this:
class UnitOfWork
{
protected $_db;
protected $_errors;
protected $_queries;
public function __construct($db) {
$this->_db = $db;
$this->_errors = array();
$this->_queries = array();
}
public function addQuery($id, $sql) {
$this->_queries[$id] = $sql;
return $this;
}
public function getErrors() {
return $this->_errors;
}
public function try() {
$this->_db->autocommit($this->_db, FALSE);
foreach($this->_queries as $id => $query) {
if ($this->_db->query($query) === FALSE) {
$this->_errors[$id] = $this->_db->error;
}
}
$hasErrors = count($this->_errors);
($hasErrors) ? $this->_db->rollback() : $this->_db->commit();
$this->_db->autocommit($this->_db, TRUE);
return !$hasErrors; // return true on success
}
}
and you could use it like
$unit = new UnitOfWork($mysqli);
$unit->addQuery('foo', 'SELECT foo FROM somewhere')
->addQuery('bar', 'SELECT bar FROM somewhereElse')
->addQuery('baz', 'SELECT baz WITH brokenQuery');
if($unit->try() === FALSE) {
print_r($unit->getErrors());
}
mysqli::affected_rows will return the number of rows affected by the last MySQL operation.
If you are doing something like this (pseudo-code) :
$db->query("insert ...");
$db->query("insert ...");
$db->query("insert ...");
$db->commit();
$num = $db->affected_rows();
You will not get the number of inserted rows : the commit instruction is the last executed one, and it doesn't "affect" any row.
If you want to know whether mysqli::commit succedeed or not, you should check it's return value (quoting) :
Returns TRUE on success or FALSE on
failure.
If it returned true, then all your previous inserts, since the beginning of the current transaction, will have been commited.
And if an error occured, you can use mysqli::errno and/or mysqli::error to get informations about it.

Categories