0

考虑一个例子:

处理公司员工的应用程序库。员工详细信息存储在 CSV 文件中(请不要对此进行判断,因为这仅用作示例)。
处理员工信息的类是(代码非常简化,只是为了给你图片):

class Staff {
    /* array containing all Staff_Emplyee objects naturally (number) indexed */
    public $employees;
    /* array containing all Staff_Employee objects $name indexed */
    public $employees_names;
    /* array containing all Staff_Team objects naturally indexed */
    public $teams;
    /* array containing all Staff_Team objects $name indexed */
    public $teams_names;

    /* parses CSV file
     * creates new Staff_Employee objects
     * creates new Staff_Team objects
     * adds references to each Staff_Employee::$managers and Staff_Employee::$team
     * adds references to Staff_Team::$managers and Staff_Team::$staff */
    public __construct();

    /* returns a single Staff_Employee object */
    public get_employee($name) {};

    /* returns a single Staff_Team object */
    public get_team($name) {};
}


class Staff_Employee {
    /* string */
    public $name;
    /* array containing all Employee's managers as Staff_Employee objects */
    public $managers;
    /* Staff_Team object of the team the Employee is in */
    public $team;
}

class Staff_Team {
    /* string */
    public $name;
    /* array of all managers in the team (Staff_Employee objects) */
    public $managers;
    /* array of all non-managers in the team (Staff_Employee objects) */
    public $staff;
}

现在,目前在应用程序中没有使用任何引用。所有对象变量都是按值传递的。我认为这可能会产生一些开销。因此,一旦创建了所有 Employee 和 Team 对象,我只需尝试将所有调用更改为引用,例如:

$team1->managers[] = &$employee1;
$employee0->managers[] = &$employee1;

但这暂时增加了内存使用量,这让我感到惊讶。我使用的示例只有 200 名员工,但我可以想象,当必须与企业打交道时,这可能会达到数千甚至更多,并且内存使用量会增长更多。

当我想到这个例子时,我试图模仿 ORM,我可以在其中做这样的事情:

$team->staff[n]->managers[n]->name; // infinite chaining?

理想情况下,“正确”(初始?)对象将只存储在Staff::$employeesand中Staff::$teams,因此Staff::$teams_names['Team Name']将是对Staff::$teams[n]. 同样是对等Staff_Team::$managers的引用数组。 但正如我所提到的 - 一旦我开始使用引用,内存使用量就会增加。Staff::$employees

问题:
那么我应该如何处理呢?
我应该使用按引用传递而不担心内存使用,还是应该使用按值传递?
在这种情况下哪个更好,为什么?

注1:我(认为我)确实理解通过值传递对象和通过引用传递对象之间的区别。我只是问在这个例子中哪个更好。
注意2: Staff_Employee 对象创建后可能会进行一些操作。不过可能非常少。

4

1 回答 1

1

简短的回答:不要使用&符号,“按值传递”(这很令人困惑,在其他语言中被称为按引用传递。)

更长的答案:我认为一些示例代码将是最具解释性的:

$a = new stdclass();
$b = $a;
$c = &$a;
$a->field = 'asdf';
echo '$b->field = ' . $b->field . "\n"; // $b->field = asdf
echo '$c->field = ' . $c->field . "\n"; // $c->field = asdf

因此,如果您只是分配给对象的字段,则没有区别。只有当您覆盖变量本身时,与号才会有所不同。

$a = new stdclass();
$b = $a;
$c = &$a;
$a = 2;
echo 'is_object($b) = ' . is_object($b) . "\n"; // is_object($b) = 1
echo 'is_object($c) = ' . is_object($c) . "\n"; // is_object($c) = 0

但一般来说,这种行为是不好的 juju (只有当你试图从一个函数返回多个值时才有用;你也可以使用它list()。)

于 2011-03-07T01:23:24.327 回答