简体   繁体   English

将$ db对象传递给其他类,以便它们可以访问数据库

[英]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. 我有一个PHP数据库类连接到MySQL并包装所有的PDO代码,我用它来查询数据库。 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. 它将PDO语句结果复制到新的assoc数组中,并仅将数据库结果返回给调用页面。 I iterate through them with a simple foreach like so: 我用一个简单的foreach迭代它们,如下所示:

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. 好吧,假设我想让另一个类使用我的$ db对象,以便它可以在某些方法中访问数据库。 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. 我不想在类中使用$ db对象的副本,我希望它使用现有的数据库对象,所以我没有多个副本使用内存浮动。

Is there any difference in PHP5 between passing it in as $db or &$db? 在以$ db或&$ db传递它之间PHP5有什么区别吗? 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. 从做一些阅读来看,PHP5默认情况下通过引用传递对象,而其他人现在说这是以Java方式进行的,有些人说使用&进行硬连接。 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++. 在PHP5中,持有对象的“$ db”基本上等同于C或C ++中的“Foo *”。 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. 换句话说,$ db不存储整个对象,它只存储一个小令牌,让代码在必要时找到对象。 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. 但是如果分配$ db,它不会更改调用者中的值,因为您正在更改包含令牌以包含其他令牌的本地变量。

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++. 如果函数采用“&$ db”,那基本上相当于在C中传递“Foo **”,或者更准确地说是在C ++中传递“Foo *&”的函数。 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. 调用同样快,因为它与传递的大小相同,但如果你分配给$ db,它会在调用者中更改$ db的值,因为“按引用传递”变量指向内存将令牌保留在呼叫者中的位置。

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. 您始终可以通过打开$ db句柄,将其传递给函数,并通过===运算符检查它们来确保它们是同一个对象来进行测试。

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);

   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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