简体   繁体   中英

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!

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.

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.

This would be a good job for static methods. That is how many frameworks accomplish the same task.

class DB
{
   private static $db = FALSE:

   public static function init($dbConfig)
   {
      if(! self:$db)
      {
         self::$db = new Database($dbConfig);
      }
   }

   public static function preparedSelect($sql, $params)
   {
      if(! self::$db)
      {
         die("call the init method first");
      }

      // db stuff, where you would call $this->db call self::$db
   }
}

So in your other classes where you want to make calls to the database all you would have to do is:

class General
{
   public function __construct()
   {
      DB::init($dbConfig);
   }

   public function someMethod()
   {
      $params = array('username' => $username);
      $result = DB::preparedSelect('select password, salt from users where username = :username', $params);

   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM