2

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';
}
5
  • 1
    ArrayAccess interface for your objects. php.net/arrayaccess Commented Jul 9, 2013 at 13:49
  • What's preventing you from doing foreach directly on the object? Commented Jul 9, 2013 at 13:50
  • Since you are not trying to cast object to string or integer without magic method, you can loop through the object Commented Jul 9, 2013 at 13:51
  • php.net/manual/en/control-structures.foreach.php - "foreach works only on arrays and objects" Commented Jul 9, 2013 at 13:51
  • oop is great, but using php stdclass objects offers none of oops benefits. in php, you should always favor regular arrays over stdclass objects when storing a collection of values, simply because the language provides the best support for arrays. Commented Jul 9, 2013 at 14:02

4 Answers 4

3

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.

Sign up to request clarification or add additional context in comments.

8 Comments

Curious. I've been using my own classes quite a bit and never had to implicitly state that they implement any of these properties. Foreach just worked. Is there some bigger picture I'm missing?
but isn't the author trying to foreach a method, which we don't know what returns
@MaximKumpan: Implicit iteration only allows access to the public properties
@RoyalBg: The OP wants to get rif of the casts, if he's not using PHP5.4+, there's no alternative to assigning the return value to a tmp var.
It's inside a class. But let's say it's: $a = new Class(); $b = $a->method() should $b get instance of stdClass in order to do foreach on it?
|
2

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';                      
}

Comments

0

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';
}

Comments

0

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';                      
}

3 Comments

additional_data is not a variable in the original question.
PHP Notice: Undefined variable: additional_data in php shell code on line 4
Thanks for pointing that out, I've removed the extra '$' now, I guess I wasn't really paying attention. OP has solved his problem now, so I guess my fix is a bit redundant now...

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.