snakeme
snakeme

Reputation: 33

Access $key of an object within a foreach loop

Since I started to write more code in OOP I always run into a in my point of view "code styling" problem. I want to add some additional data to an existing object. When I used arrays this was easily possible with foreach because every array item got its own key. Now with objects I didn't found a way how I can access each item with an key.

$data_items = $this->model->get_function();
$data_items = (array) $data_items;
foreach ($data_items as $key => $row)
{
      $data_items[$key]['additional_data'] = 'additional_data';                      
}
$data_items = (object) $data_items;

I think my code is only a work around. Can please somebody tell me if I can get rid off the code line "$data_items = (array) $data_items;" and "$data_items = (object) $data_items;".

Thanks to everybody who replied to my question!

Until now I didn't realized that it is so easy what I tried to achieve:

foreach ($data_items as $row)
{
    $row->additional_data = 'additional_data';
}

Upvotes: 2

Views: 9481

Answers (4)

andyc
andyc

Reputation: 177

You should be able to do something like this:

$data_items = $this->model->get_function();
foreach ($resource_contacts as $key => $row)
{
      $data_items->$key->additional_data = 'additional_data';                      
}

Upvotes: 0

Maxim Kumpan
Maxim Kumpan

Reputation: 2635

Objects and arrays look pretty much the same from the viewpoint of data handling. You can simply add another object property and save your data to it without having to declare said property (in my opinion, it's a drawback, but in your case - an advantage).

Array:

$arr = array();
$arr['additional_data'] = 'foo';

Object:

$obj = new stdClass;
$obj->additional_data = 'bar';

Foreach will handle object properties just the same as it will handle array keys. And no need for implicit casting.

Here's the cast-free variant:

$data_items = $this->model->get_function();
foreach ($resource_contacts as $key => $row)
{
      // Note, $data_items->{$key} must be an object, or this will crash.
      // You can check if it is with is_object() and react accordingly
      $data_items->{$key}->additional_data = 'additional_data';                      
}

Upvotes: 2

Elias Van Ootegem
Elias Van Ootegem

Reputation: 76413

If the object implements the Traversable interface (ArrayAccess, Iterable), like the stdClass, you can easily foreach the instance:

$foo = new stdClass;
$foo->bar = 'foobar';
foreach($foo as $property => $value)
{
    echo '$foo->'.$property.' === '.$value;
    echo $foo->{$property} = 'reassign';
}

Without implementing these interfaces, you'll still be able to iterate over any object, however: only the public properties will be visible.
To get around this, I tend to declare all my properties as protected, and have all my data objects inherit from an abstract model, that implements the Iterator interface, so I don't have to worry about it.

Upvotes: 3

RedPoppy
RedPoppy

Reputation: 623

Use references to be able to modify your object inside the foreach loop, if that is what you are trying to achieve:

foreach($objectList as &$obj){
    $obj->newProperty = 'whatever';
}

Upvotes: 0

Related Questions