0

I'm trying to make oop class to get user info but i get this error

Fatal error: Call to a member function prepare() on a non-object in functions.php

user.php - >

include_once 'functions.php';
$user = new User();

echo $user->get_fullname(5);

functions.php ->

include_once 'database.php';
class User 
{
    public function connect()
    {
        $dbh = new DB_Class();
    }

    public function get_fullname($uid)
    {

        $getName = $dbh->prepare("SELECT EmailAddress FROM users WHERE UserID =:username");
        $getName->bindParam(':username', $uid);
        $getName->execute();
        $rowName = $getName->fetch();
        $email = $rowName['emailaddress'];
        return $email;

    }    
}

database.php - >

class DB_Class
{
    public function connect() {
        try {
            $dbh= new PDO("mysql:host=localhost;dbname=root",'users','password', array(
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
            ));
        } catch (PDOException $e) {
            echo $e->getMessage();
        }

        $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
        $dbh->setAttribute(PDO::ATTR_CASE,PDO::CASE_LOWER);
    }

}

What i'm doing wrong :(

tereško
  • 58,060
  • 25
  • 98
  • 150
Ben
  • 1,906
  • 10
  • 31
  • 47

4 Answers4

1

You never actually give access to the PDO instance $dbh to the things youre trying to use it in. It seems like youre using classes simple as groupings of functions but also expecting some magic to happen :-) This is how i would do it with your existingcode:

class DB_Class {

    protected $dsn;
    protected $user;
    protected $password;

    protected $connection;

    public function __construct($dsn = null, $user = null, $password = null)
    {
        $this->dsn = $dsn;
        $this->user = $user;
        $this->password = $password;
    }

    public function connect()
    {
       if($this->connection) {
         return $this->connection;
       }

       try {
         $this->connection = new PDO($this->dsn,$this->user, $this->password, 
            array(
              PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
              PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
         ));

         $this->connection->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
         $this->connection->setAttribute(PDO::ATTR_CASE,PDO::CASE_LOWER);

         return $this->connection;
       }
       catch (PDOException $e) {

          return false;
       }

    }
}

class User {
    protected $db;

    public function __construct(DB_Class $db = null) 
    {
        $this->db = $db;
    }

    public function setDb(DB_Class $db)
    {
       $this->db = $db;
    }



    public function get_fullname($uid)
    {
        $stmt = $this->db->connect()->prepare("SELECT EmailAddress FROM users WHERE UserID =:username");
        $stmt->execute(array(':username', $uid));
        if($row = $getName->fetch()) {
           return $row['emailaddress'];
        } else {
           return null;
        }
    }

}
prodigitalson
  • 60,050
  • 10
  • 100
  • 114
  • I see u edit the code but stil it shows Fatal error: Call to a member function connect() on a non-object – Ben Mar 07 '12 at 21:07
  • did you create a new `DB_Class` instance and pass it in to `User`? `$user = new User(new DB_Class('your dsn', 'your_username', 'your_password')); echo $user->get_fullname();` – prodigitalson Mar 07 '12 at 21:07
  • Fatal error: Uncaught exception 'PDOException' with message 'invalid data source name' .. – Ben Mar 07 '12 at 21:20
  • Then your `dsn` has an issue not necessarily your code. You need to trouble shoot your db connection particularly the `dbname`. Can you connect to the db with the same parameters using the commandline client? – prodigitalson Mar 07 '12 at 21:24
  • ohh i have placed the new code before wrong } .. :D everything works fine.Thanks – Ben Mar 07 '12 at 22:25
0

The $dbh variable isn't being passed into the get_fullname function. You'd need to do something like:

public function connect()
{
    $dbh = new DB_Class();
    return $dbh;
}

public function get_fullname($uid)
{
    $dbh = $this->connect();
enygma
  • 684
  • 4
  • 6
  • Another error: Fatal error: Call to undefined method DB_Class::prepare() in functions.php – Ben Mar 07 '12 at 20:43
0

you need to declare $dbh as property of User class and access it via $this identifier:

class User 
    {
protected $dbh;
    public function connect()
    {
    $this->dbh = new DB_Class();
    }

    public function get_fullname($uid)
    {

$getName =$this->dbh->prepare("SELECT EmailAddress FROM users WHERE UserID =:username");
$getName->bindParam(':username', $uid);
$getName->execute();
$rowName = $getName->fetch();
    $email = $rowMail['emailaddress'];
    return $email;

    }

    }
heximal
  • 10,327
  • 5
  • 46
  • 69
  • Another error: Fatal error: Call to undefined method DB_Class::prepare() in functions.php – Ben Mar 07 '12 at 20:47
  • 1
    it depends on what level of abstraction do you want to implenment. if you design special class DB_class for low-level interaction with database it makes sense to incapsulate db-quiries within this class. Class User in this model shouldn't know anything about physical properties of DB layer it should only contain business logic. It's hard to describe in a couple of words. – heximal Mar 07 '12 at 21:04
0

You are never actually assigning your class properties as a property, all you are doing when declaring the variables inside of your methods is putting them into the methods current scope and they are destroyed once the method finishes execution.

To properly set a property within a class you need to declare them using $this->varname and the same goes for accessing them.

You are also using an incorrect name for the classes construction, the constructor must be set to __construct not connect.

As you can see in the updated code the $dbh variable is now a property of the User class and can be called between it's methods.

User Class

class User 
{
    public function __construct()
    {
        $this->dbh = new DB_Class();
    }

    public function get_fullname($uid)
    {

        $getName = $this->dbh->getConnection()->prepare("SELECT EmailAddress FROM users WHERE UserID =:username");
        $getName->bindParam(':username', $uid);
        $getName->execute();
        $rowName = $getName->fetch();
        $email = $rowName['emailaddress'];
        return $email;

    }    
}

Database Class

class DB_Class
{
    public function __construct() {
        try {
            $this->dbh = new PDO("mysql:host=localhost;dbname=root",'users','password', array(
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
            ));
        } catch (PDOException $e) {
            echo $e->getMessage();
        }

        $this->dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
        $this->dbh->setAttribute(PDO::ATTR_CASE,PDO::CASE_LOWER);
    }

    public function getConnection() {
        return $this->dbh;
    }
}

You will benefit greatly by using http://us2.php.net/manual/en/oop5.intro.php as a resource.

Nick
  • 763
  • 1
  • 11
  • 26
  • Fatal error: Call to a member function prepare() on a non-object again :X – Ben Mar 07 '12 at 22:06
  • Answer has been updated as I overlooked how you are constructing your class. – Nick Mar 07 '12 at 22:09
  • If i use the edited code the error is : Fatal error: Call to undefined method DB_Class::prepare() .. – Ben Mar 07 '12 at 22:12
  • No it dosent work . :X :X Parse error: syntax error, unexpected T_PUBLIC in database.php – Ben Mar 07 '12 at 22:22
  • This was not intended to be a drop-in replacement but an example for you to learn and write the code on your own, so in the future you dont need to re-ask the same question again. If I had 125 reputation I would down vote this question. – Nick Mar 07 '12 at 22:30