Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing $db object to other classes so they can access the database

I've got a PHP database class which connects to MySQL and wraps up all the PDO code and I use it to query the database. Basically in the page controller I make a new object:

$db = new Database($dbConfig);

Then I can get data from the database like so using a prepared query:

$params = array('username' => $username);
$result = $db->preparedSelect('select password, salt from users where username = :username', $params);

Which copies the PDO statement results into a new assoc array and returns just the database results back to the calling page. I iterate through them with a simple foreach like so:

foreach ($result as $key => $val)
{
   $password = $val['password'];
   $salt = $val['salt'];
}

Ok so lets say I want another class to use my $db object so it can access the database in some of the methods. At the moment the other class looks like this:

class General
{
    // Database object
    private $db;

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

That works well but I'm just wondering if the constructor should look like this:

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

That should mean I'm passing it in via reference and not copying the object into the other class. I don't want a copy of the $db object inside the class, I want it to use the existing database object so I don't have multiple copies of it floating around using up memory.

Is there any difference in PHP5 between passing it in as $db or &$db? From doing some reading, PHP5 by default passes objects by reference, and other people saying it now does it the Java way and some say using the & makes a hard link whatever that is. I'm confused. What's the best way to do it?

Many thanks!

like image 683
zuallauz Avatar asked Mar 06 '11 04:03

zuallauz


2 Answers

There is a difference, but it's not really the difference you may think.

In PHP5, "$db" holding an object is basically equivalent to a "Foo *" in C or C++. In other words, $db doesn't store the whole object, it just stores a small token that lets the code find the object when necessary. When you pass this token by value, it's as fast as passing an integer value rather than a copy of the entire object. But if you assign $db, it doesn't change the value in the caller because you're changing your local variable holding the token to contain a different token.

If the function takes "&$db", that's basically the equivalent of passing "Foo **" in C, or more correctly a function taking a "Foo *&" in C++. The call is just as fast since it's the same size thing that's being passed, but inside the function if you assign to $db it will change the value of $db in the caller because the "pass by reference" variable points you to the memory location holding the token in the caller.

The best way to do it is to pass by value (do not use "&") unless you know what you're doing and why you're doing it.

like image 72
Anomie Avatar answered Nov 03 '22 01:11

Anomie


That's a good question.

You can always do a test by opening a $db handle, passing it to a function, and checking them via the === operator to make sure they are the same object.

like image 21
ThinkingInBits Avatar answered Nov 03 '22 00:11

ThinkingInBits