2

我最近开始重组我用于项目的一些“复制粘贴”数据库类。我正在处理登录类并遇到了一个有趣的功能。

我的 Login 类有一个如下所示的函数:

function &db_connect() {
    require_once('mysql.php');
    $db = new DB();
    return $db;
}

有趣的是它返回对$db对象的引用而不是实际对象。没关系,但后来我遇到了这个:

function __construct(&$db) {
    $this->db = $db;
    $this->date = $GLOBALS['date'];
    if ($_SESSION['logged']) {
        $this->_checkSession();
    }
}

该代码是这样使用的:

$db = db_connect();
$user = new User($db);

如您所见,实际发生的是我传递了对DB实例的引用而不是实际对象。显然,我在 3 年前编写这段代码时有我的理由,所以现在我想知道,为什么?

我所有的“数据库”类和对象都应该通过引用传递吗?简单地通过值传递,比如说,一个 PDO 对象,会导致它创建新的连接吗?什么是正确的做法,我应该使用什么?

4

2 回答 2

2

存储在变量中的值是对象引用。按值传递这个引用通常是这样做的——这&是不必要的,并且在这里没有任何好处。

如果你$db在构造函数中赋值,这会改变你传入的变量的值:

$a = 1;

function foo(&$p) {
    $p = 2;
}

foo($a);
// $a is now 2

我认为&在这种情况下使用是错误的,因为如果您将代码更改为分配给$db. 突然间,调用者也会看到他们的变量发生变化。

于 2013-09-29T07:14:45.747 回答
0

以下程序说明了 PHP 5 如何将对象作为参数处理:

<?php

class Foo {
  public $value;
  public function __construct($value) { $this->value = $value; }
}

function swap      ($a, $b)   { $tmp = $a; $a = $b; $b = $tmp; }
function swap_refs (&$a, &$b) { $tmp = $a; $a = $b; $b = $tmp; }
function inc       ($a, $b)   { ++$a->value; ++$b->value; }

$a = new Foo(1); $b = new Foo(2);

swap ($a, $b);
printf("swap():      \$a %d, \$b %d\n", $a->value, $b->value);

swap_refs ($a, $b);
printf("swap_refs(): \$a %d, \$b %d\n", $a->value, $b->value);

inc($a, $b);
printf("inc:         \$a %d, \$b %d\n", $a->value, $b->value);

它打印出来

swap():      $a 1, $b 2
swap_refs(): $a 2, $b 1
inc:         $a 3, $b 2
于 2013-09-29T07:35:20.310 回答