0

My problem is that I have an object shared through two classes that contains an array inside of it and along the script, someone will request some of the classes the value and a foreach loop will change such value and I want this change to affect every reference of the value.

class bar {

    protected $obj;

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

    public function output() {
        print_r($this->obj->value);
    }

}

class foo {

    protected $obj;

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

    public function val() {
        $result = array();
        foreach($this->obj->value as $it){
            $result[] = $it;
        }
        return $result;
    }

}
// Shared Object
$obj = new stdClass();
// Default value
$obj->value = array('teste', 'banana', 'maca');
// Class 1
$bar = new bar($obj);
// Class 2
$foo = new foo($obj);

// Someone requests from class 2 the values and changes it
$new = $foo->val();
$new[] = 'abc';

// Class 1 outputs the value
$bar->output(); // this will print the default value. I want this to also have 'abc' value.

1 Answer 1

2

The main problem, is that you are building a new array at foo:val, you must return the original object to be modified.

I suggest use ArrayObject, have the same behavior of array but is a object, then always is passed by reference.

<?php

class MyArrayObject extends ArrayObject {
    public function replace(Array $array)
    {
        foreach($this->getArrayCopy() as $key => $value) {
            $this->offsetUnset($key);
        }

        foreach ($array as $key => $value) {
            $this[$key] = $value;
        }
    }


}

class bar {

    protected $obj;

    function __construct(MyArrayObject $obj) {
        $this->obj = $obj;
    }

    public function output() {
        print_r($this->obj);
    }

}

class foo {

    protected $obj;

    function __construct(MyArrayObject $obj) {
        $this->obj = $obj;
    }

    public function val() {
        $result = array('foo', 'bar');
        $this->obj->replace($result);

        return $this->obj;
    }

}
// Shared Object
$obj = new MyArrayObject(array('teste', 'banana', 'maca'));
// Class 1
$bar = new bar($obj);
// Class 2
$foo = new foo($obj);

// Someone requests from class 2 the values and changes it
$new = $foo->val();
$new[] = 'abc';

// Class 1 outputs the value
$bar->output(); // this will print the default value. I want this to also 

var_dump($obj);
Sign up to request clarification or add additional context in comments.

3 Comments

My problem is that I actually filter the array before returning it, that's why I'm "building a new array". I'd like this new array to point to the original values.
the arrayobject is your choose you can empty it and fill it again.
I may have not been fair on the question since my values were being filtered and they weren't primitive, it was actually objects. Building a new function inside the class of objects that changes itself did the trick. But thanks, you showed me that the problem was the creation of new arrays.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.