-2

[SOLVED] The Answer in Here Class query PDO property of non-object

I get this error when trying to display the record using while.

Notice: Trying to get property of non-object in "$contacts[] = $obj;

and this my code

public function selectAll($connect,$order) {
        if ( !isset($order) ) {
            $order = "name";
        }
        $dbIdO=$this->anti_injection($order);
        $dbres =$connect->prepare("SELECT * FROM contacts ORDER BY '".$dbIdO."' ASC");
        $dbres->execute();
        $contacts = array();
        while ($obj = $dbres->fetchAll(PDO::FETCH_ASSOC) != NULL ) {
            $contacts[] = $obj;
        }

        return $contacts;
    }

The connection code

<?php 

class ContactsService {

    private $contactsGateway    = NULL;

        var $myconn;

    public function openDb() {

        $servername = "localhost";
        $username = "root";
        $password = "";
        $dbname = "sample";
        $myconn;


    try{
        $conn = new PDO("mysql:host=$servername;dbname=$dbname",$username,$password);
        //ser the pdo error mode to exception
        $conn->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
        echo "Connect Successfully";
        $this->myconn = $conn;
    }
    catch(PDOException $e)
    {
        echo "Connection failed: " . $e->getMessage();
    }
            return $this->myconn;    
    }

    private function closeDb() {
        $this->myconn = null;
    }

    public function __construct() {
        $this->contactsGateway = new ContactsGateway();
    }

    public function getAllContacts($order) {
        try {
            $this->openDb();
            $connect = $this->myconn;
            $res = $this->contactsGateway->selectAll($connect,$order);
            $this->closeDb();
            return $res;
        } catch (Exception $e) {
            $this->closeDb();
            throw $e;
        }
    }

    public function getContact($id) {
        try {
            $this->openDb();
            $res = $this->contactsGateway->selectById($id);
            $this->closeDb();
            return $res;
        } catch (Exception $e) {
            $this->closeDb();
            throw $e;
        }
        return $this->contactsGateway->find($id);
    }

    private function validateContactParams( $name, $phone, $email, $address ) {
        $errors = array();
        if ( !isset($name) || empty($name) ) {
            $errors[] = 'Name is required';
        }
        if ( empty($errors) ) {
            return;
        }
        throw new ValidationException($errors);
    }

    public function createNewContact( $name, $phone, $email, $address ) {
        try {
            $this->openDb();
            $this->validateContactParams($name, $phone, $email, $address);
            $res = $this->contactsGateway->insert($name, $phone, $email, $address);
            $this->closeDb();
            return $res;
        } catch (Exception $e) {
            $this->closeDb();
            throw $e;
        }
    }

    public function deleteContact( $id ) {
        try {
            $this->openDb();
            $res = $this->contactsGateway->delete($id);
            $this->closeDb();
        } catch (Exception $e) {
            $this->closeDb();
            throw $e;
        }
    }


}

?>

normally when i return the while use mysqli, this query work. but when i change to pdo i not get the result just the notice.

Community
  • 1
  • 1
Riski Febriansyah
  • 335
  • 1
  • 8
  • 21

2 Answers2

2

I went with the below to show a few things that might be important to know. The code is commented inside. SpecimenA is your code. SpecimenB shows fetch(), SpecimenC shows fetchAll.

Part of the problem with your fetchAll is that it has no business being in a while loop. It fetches all. That is why I showed SpecimenB and C as alternatives for you to consider.

Schema

create table myUsers
(   userId int not null,
    screenName varchar(40) not null
);
insert myUsers (userId,screenName) values (101,'Johnny'),(107,'mustard');

The Code (with embedded results)

<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);

    try {
        $db = new PDO('mysql:host=localhost;dbname=stackoverflow;charset=utf8', 'dbusername', 'dbpassword');
        $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

        echo "Connected and Happy<br>";
        $dbIdO="screenName";
        $sql="SELECT userId,screenName FROM myUsers ORDER BY ".$dbIdO;  // ASC is unnecessary
        echo $sql."<br>";
        print "--------------------------<br>";
        $dbres = $db->prepare($sql);
        $dbres->execute();
        $contacts = array();

        # note the below SpecimenA is from the OP code (yours)

        #########################################################
        # OP code
        # SpecimenA (I calling this block here that)
        # gets this out in var_dump: array(1) { [0]=> bool(true) }
        # it even gets that output if select stmt errantly has single quotes around the variable
        #
        # while ($obj = $dbres->fetchAll(PDO::FETCH_ASSOC) != NULL ) {
        #     $contacts[] = $obj;
        # }
        # var_dump($contacts);
        # 
        #########################################################

        #########################################################
        # SpecimenB fetch (I calling this block here that)
        # show it with fetch()
        #
        # print "I am running SpecimenB<br>";
        # print "--------------------------<br>";
        # while($user = $dbres->fetch( PDO::FETCH_ASSOC )){ 
        #   print $user['userId']."<br>";
        #   print $user['screenName']."<br>";
        #   print "--------------------------<br>";
        # }
        # 
        # TOTAL Output From Top of Script down:
        # Connected and Happy
        # SELECT userId,screenName FROM myUsers ORDER BY screenName
        # --------------------------
        # I am running SpecimenB
        # --------------------------
        # 101
        # Johnny
        # --------------------------
        # 107
        # mustard
        # --------------------------
        #########################################################

        #########################################################
        # SpecimenC fetchAll (I calling this block here that)
        # show it with fetchAll()
        #
        # print "I am running SpecimenC<br>";
        # print "--------------------------<br>";
        # $users = $dbres->fetchAll( PDO::FETCH_ASSOC );    // this is a one-liner not wrapped in a while (like yours)
        # foreach ($users as $user){        // now here is the loop as we whip through the associative array
        #   print $user['userId'] ."<br>";
        #   print $user['screenName'] ."<br>";
        #   print "--------------------------<br>";
        # }
        # TOTAL Output From Top of Script down:
        # Connected and Happy
        # SELECT userId,screenName FROM myUsers ORDER BY screenName
        # --------------------------
        # I am running SpecimenC
        # --------------------------
        # 101
        # Johnny
        # --------------------------
        # 107
        # mustard
        # --------------------------
        #########################################################

    } catch (PDOException $e) {
        echo 'PDO Exception: ' . $e->getMessage();
        exit();
    }
?>

The order by works fine, as seen if I put DESC at the end of it, such that screenName mustard comes before screenName Johnny.

I agree with much/most of what YCS said, except for the order by piece (and that it can't be made to work). Plus I wanted to show you the proper use of fetch and fetchAll (with loops). So shoot for SpecimenB or SpecimenC

good luck

Drew
  • 24,851
  • 10
  • 43
  • 78
-1

This question is not a real one.

$contacts[] = $obj; line cannot raise a Notice: Trying to get property of non-object error, as there are no properties involved in this line.

There are no [visible] syntax errors in your code.

Most likely there is no SQL error either, as if there were any, an exception should have been raised, but it weren't.

Apart from of all that, your order by will never work the way you expecting. Instead of quoting the field name you should filter it against a white list, as shown here

Also, the loop you wrote will never return data the way you expect it. Trying to make it "proper" you actually spoiled it. What you wanted to write is

    while ($obj = $dbres->fetch(PDO::FETCH_ASSOC)) {
        $contacts[] = $obj;
    }

and what you really need is

    $contacts = $dbres->fetchAll(PDO::FETCH_ASSOC);
Community
  • 1
  • 1
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345