6

如何将引用传递给对象构造函数,并允许该对象更新该引用?

class A{
    private $data;
    function __construct(&$d){
        $this->data = $d;
    }
    function addData(){
        $this->data["extra"]="stuff";
    }
}

// Somewhere else
$arr = array("seed"=>"data");
$obj = new A($arr);
$obj->addData();

// I want $arr to contain ["seed"=>"data", "extra"=>"stuff"]
// Instead it only contains ["seed"=>"data"]
4

3 回答 3

12

您必须将其存储在任何地方作为参考。

function __construct (&$d) {
    $this->data = &$d; // the & here
}
于 2013-04-05T20:03:14.480 回答
2

您必须告诉 PHP 也为私有成员分配一个引用,data如下所示:

$this->data = &$d;

根据上下文,您可能不想使用对外部数组的引用,最好将该数组放在处理它的对象中。

另外请注意,构造函数被称为__constructnot __construction

于 2013-04-05T20:06:30.803 回答
1

这将满足您的要求:

class Test {

    private $storage;

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

    public function fn()
    {
        $this->storage[0] *= 10;
    }
}

$storage = [1];

$a = new Test($storage);
$b = new Test($storage);

$a->fn();
print_r($a); // $storage[0] is 10
print_r($b); // $storage[0] is 10

$b->fn();
print_r($a); // $storage[0] is 100
print_r($b); // $storage[0] is 100

备选方案 1

除了使用数组,您还可以使用ArrayObject,ArrayIteratorSplFixedArray。由于这些是对象,它们将通过引用传递。所有这些实现ArrayAccess,因此您可以通过方括号访问它们,例如

$arrayObject = new ArrayObject;
$arrayObject['foo'] = 'bar';
echo $arrayObject['foo']; // prints 'bar'

备选方案 2

不要使用泛型类型,而是使用专用类型。找出您在该数组中存储的内容。是Config吗?一个Registry?一个UnitOfWork?找出它到底是什么。然后让它成为一个对象,并给它一个反映职责的 API。然后注入该对象并通过该 API 访问它。

有关何时制作类型的一些指导,请参阅 Martin Fowler 的这篇论文

于 2013-07-09T08:56:13.497 回答