2

PHP 5.5

I'm doing a bunch of passing around of objects with the assumption that they will all maintain their identities - that any changes made to their states from inside other objects' methods will continue to hold true afterwards. Am I assuming correctly?

I will give my basic structure here.

class builder {
  protected $foo_ids = array(); // set in construct
  protected $foo_collection;
  protected $bar_ids = array(); // set in construct
  protected $bar_collection;
  protected function initFoos() {
    $this->foo_collection = new FooCollection();
    foreach($this->food_ids as $id) {
      $this->foo_collection->addFoo(new foo($id));
    }
  }
  protected function initBars() {
    // same idea as initFoos
  }
  protected function wireFoosAndBars(fooCollection $foos, barCollection $bars) {
    // arguments are passed in using $this->foo_collection and $this->bar_collection
    foreach($foos as $foo_obj) { // (foo_collection implements IteratorAggregate)
      $bar_ids = $foo_obj->getAssociatedBarIds();
      if(!empty($bar_ids) ) {
        $bar_collection = new barCollection(); // sub-collection to be a component of each foo
        foreach($bar_ids as $bar_id) {
          $bar_collection->addBar(new bar($bar_id));
        }
        $foo_obj->addBarCollection($bar_collection);
        // now each foo_obj has a collection of bar objects, each of which is also in the main collection. Are they the same objects?
      }
    }
  }

}

What has me worried is that foreach supposedly works on a copy of its arrays. I want all the $foo and $bar objects to maintain their identities no matter which $collection object they become of a part of. Does that make sense?

EDIT: My understanding is that using the clone keyword is the only way to really copy an object in PHP 5+. Using the assignment operator basically just creates another reference to the same object. I'm hoping that return values and foreach also work that way.

3
  • PHP doesn't have pointers, use need to pass by reference &$object to not pass the object by value. Passing a copy and manipulating it will have effect in the scope of the method.
    – Ryan
    Commented Jun 8, 2014 at 3:51
  • Are you sure about that? I just found this stackoverflow question whose chosen answer states that you do not need to use & with objects. I suppose that fairly soon I will find out for myself once my code is wired and I start testing it. SO: stackoverflow.com/questions/2715026/… Commented Jun 8, 2014 at 18:12
  • @RPM That hasn't been true since PHP 5.0.0. Class instances are always passed by reference (with some caveats, php.net//manual/en/language.oop5.references.php)
    – GordonM
    Commented Jun 23, 2014 at 8:27

1 Answer 1

1

No, they are not the same bars, since you are calling new. Also I don't see $bars being used anywhere in wireFoosAndBars.

Use the exact "associated" instances from $bars when constructing the new collection and they will be the same objects.

You are correct in that clone is the only way to make a copy of an object. Modifying an object's properties, no matter how indirectly, whether the property is an array or not, will always modify the property in that object.

You don't need to use references for objects, it's superfluous.

$foo = new Foo(); $foo->x = []; function doSomething($object) { $object2 = $object; $object2->x[0] = 'hello'; } doSomething($foo); var_dump($foo->x); // array(0=>'hello')

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.