当你在 php 中通过引用传递一个对象时会发生什么?

Aro*_*ron 2 php oop pass-by-reference

任何知道的人的问题。PHP文档(用于 php5)明确指出,在 php 中不要通过引用传递对象,因为对于接受对象的方法,实际传递的值是“允许对象访问者找到实际对象的对象标识符” . 问题是,当您实际执行此操作时会发生什么?

考虑以下代码:

<?php
function foo(&$arg){
    if(is_array($arg)){
         print $arg['foo'];
    }
    if(is_object($arg)){
        print $arg->{'foo'};
    }
}
$o1 = new \stdClass;
$o1->foo = 'bar';
$a1 = ['foo'=>'bar'];
print sprintf("O1 foo: %s", foo($o1));
print sprintf("a1 foo: %s", foo($a1));
Run Code Online (Sandbox Code Playgroud)

这正确输出:

o1 foo: bar
a1 foo: bar
Run Code Online (Sandbox Code Playgroud)

问题是为什么?谁能描述这个仍然允许访问实际对象的对象标识符引用发生了什么?

dec*_*eze 5

任何持有对象的变量都不直接持有该对象。它持有对象的标识符。把它想象成生活在对象池中某处的对象,上面附有一个数字,例如#5。所有变量包含的是"object #5"。PHP 知道该变量引用了一个对象,并且它应该是对象#5。

每当您使用这样一个保存对象引用的变量时,PHP 都会从对象池中查找被引用的对象。

当您将这样的变量传递给函数时,PHP会复制该引用。然后有两个变量保存内容"object #5"。没有复制对象本身,只是这个写着“对象#5”的小纸条。

当您通过引用将这样的变量传递给函数时,您是通过引用传递该注释“对象#5”。PHP 不会复制它。但它仍然只是一个表示"object #5"的变量,因此当您尝试使用它时,PHP 将从池中查找该对象。

这种对象引用机制与&传递引用机制不同。对象引用机制的工作原理与所有其他传值操作完全相同;只是表示对象引用的值总是以特定方式处理(PHP 必须在别处查找实际对象)。