Matt
Matt

Reputation: 179

PHP OOP call to database inside a class

I'm really confused to what is the proper way of interfacing with a database from inside a class, I know I'm doing it wrong below, but I still would've expected it to work at least?

class User{


    public function user_email($user_id){

        require_once("config/db.php");

        $finduser = $db->query("SELECT email FROM `user` WHERE user_id = '".$user_id."' ");

        $user_data = $finduser->fetch_assoc();

        return $user_data["email"];

    }

}

And then I am using the code below to display the result on another page, this first instance works fine, but the second throws an error.

<?php echo $user->user_email($user_id); ?>
<?php echo $user->user_email($user_id); ?>

Notice: Undefined variable: db on line 89
Fatal error: Call to a member function query() on a non-object on line 89

So what I'm basically asking is, what would be a good way of interfacing to a database from a class where the connection to the database is in one location?

Thanks for your help!

Upvotes: 1

Views: 2196

Answers (2)

prodigitalson
prodigitalson

Reputation: 60413

You should look at what @leneya has in his/her answer, its pretty much the way to go.

However, if you are not just doing this as a learning endeavor I would encourage you to use Doctrine2 ORM.

Now on to your specific question...


You should be injecting the connection into the class. In its simplest form:

class User {
   protected $conn;

   public function __construct(mysqli $conn) {
     $this->conn = $conn;
  }

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

  public function user_email($user_id){


    $finduser = $this->getConnection()->query("SELECT email FROM `user` WHERE user_id = '".$user_id."' ");

    $user_data = $finduser->fetch_assoc();

    return $user_data["email"];

  }
}

Then usage would look like:

require 'connection.php';
$user = new User($db);
$email = $user->user_email($userid);

I would also change the connection.php to return the mysqli object that way you arent declaring a var in a separate file:

// connection.php

// vars and stuff for the connection
// and then we return the instance
return new Mysqli($host, $user, $pass, $dbname); 

Now when you use this you can do

$db = require('connection.php');
$user = new User($db);
$email = $user->user_email($userid);

Having said that this is a very odd design you have going. Typically you would use getters to access properties on a full user object and to run queries for specific things.

Upvotes: 1

xJoshWalker
xJoshWalker

Reputation: 457

For a database connection, I would recommend separating database access out of your class all together. Your User class should only handle being a user, it shouldn't know where it's data is coming from.

I would suggest using different classes for different responsibilities.

For instance,

Repositories

Should handle retrieving full objects from your database. They will return a collection of (or just one) objects from the database, and fill in their information with the persisted data from the database.

Entities or Model

Should just deal with business logic. This would mean that instead of call the database to get the user's email, you would instead load the entire user object data from the database and then set it on the User object that you displayed here. The way that I would do that (without using an ORM like Doctrine or Propel or any other ORM that comes with an MVC framework) would be to create a function on your object called "setByArray", which would take a keyed array that would set all of the data on your object based on the results that you found from the database.

So really, your database access should be abstracted away from your actual class. By using the database within your class you are violating the single responsibility principle of the SOLID OOP principles. Your User class should only be concerned with being a user. Not with how to access it's data.

Edit

Sorry, I missed you trying to get it to "just work". Are you sure that your "config/db.php" is actually a path that has a variable called $db in it? Are you sure that $db is is actually the object that has a query function on it? From what I'm seeing, $db is not an object.

Upvotes: 1

Related Questions