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

时间:2011-03-06 04:43:39

标签: php database oop pass-by-reference

我有一个PHP数据库类连接到MySQL并包装所有PDO代码,我用它来查询数据库。基本上在页面控制器中我创建了一个新对象:

$db = new Database($dbConfig);

然后我可以使用准备好的查询从数据库中获取数据:

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

将PDO语句结果复制到新的assoc数组中,并将数据库结果返回给调用页面。我用一个简单的foreach迭代它们:

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

好吧,让我们说我希望另一个类使用我的$ db对象,以便它可以在某些方法中访问数据库。目前另一堂课看起来像这样:

class General
{
    // Database object
    private $db;

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

这很好但我只是想知道构造函数是否应该如下所示:

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

这应该意味着我通过引用传递它而不是将对象复制到另一个类中。我不想在类中使用$ db对象的副本,我希望它使用现有的数据库对象,因此我没有多个副本使用内存浮动。

PHP5在以$ db或& $ db传递之间有什么不同吗?从做一些阅读来看,PHP5默认情况下通过引用传递对象,其他人现在说它是以Java方式进行的,有些人说使用&无论那是什么,都会发生一些困难。我糊涂了。最好的方法是什么?

非常感谢!

3 个答案:

答案 0 :(得分:8)

存在差异,但这并不是你想到的差异。

在PHP5中,持有对象的“$ db”基本上等同于C或C ++中的“Foo *”。换句话说,$ db不存储整个对象,它只存储一个小令牌,让代码在必要时找到对象。按值传递此标记时,它与传递整数值而不是整个对象的副本一样快。但是如果你分配$ db,它不会改变调用者的值,因为你正在改变你的局部变量,持有令牌以包含不同的令牌。

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

最好的方法是传递价值(不要使用“&”),除非你知道自己在做什么以及为什么要这样做。

答案 1 :(得分:3)

这是一个很好的问题。

您总是可以通过打开$ db句柄,将其传递给函数,并通过===运算符检查它们来确保它们是同一个对象来进行测试。

答案 2 :(得分:3)

这对于静态方法来说是一个很好的工作。这就是有多少框架完成同样的任务。

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
   }
}

因此,在您想要调用数据库的其他类中,您所要做的就是:

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

   }
}