dot
dot

Reputation: 15660

php - adding values in an array

I'm trying to loop through a multidimensional array, and add a new sub array. My code doesn't return any errors, but it also doesn't add the new item.

I have the following code:

foreach ($data['switches'] as $switch) {
    foreach ($switch['atags'] as $attributelist)  {
        $nohardwareAttribFound = false;

        foreach ($attributelist as $attribute) {
            $pos =  strpos(trim($attribute),'$attr_2_');

            if ($pos !==false)   {      

                //echo 'in the loop';
                //found it.  extract and exit loop
                $modelnumber = substr(trim($attribute),8);
                $hardwaremodel = array();
                $hardwaremodel['tag'] = 'hardware_model:'.$modelnumber;
                array_push($switch['atags'],$hardwaremodel);
                print_r($switch);
                //echo '<br>=====<br>';
                $nohardwareAttribFound = true;
            }   

        }//end foreach ($attributelist
    }// end foreach ($switch['atags']

    if ($nohardwareAttribFound==false) {
        $hardwaremodel['tag'] = 'Unknown';
        array_push($switch['atags'],$hardwaremodel);
    }//end if


}// end foreach ($data['switches']

I would like the data to look like:

[atags] => Array ( 
  [0] => Array ( [tag] => $id_365 ) 
  [1] => Array ( [tag] => $typeid_8 ) 
  [2] => Array ( [tag] => $any_object ) 
  [3] => Array ( [tag] => $casd ) 
  [4] => Array ( [tag] => $unmounted ) 
  [5] => Array ( [tag] => $no_asset_tag ) 
  [6] => Array ( [tag] => $attr_2_1086 ) 
  [7] => Array ( [tag] => $untagged ) 
  [8] => Array ( [tag] => hardware_model:1086 ) ) ) 

where the last array - element [8], represents a new subarray that I've added. The print_r() statement looks correct, but when I loop through the results that are passed to my view, i can see that in fact, a new tag array has not been added.

Do i need to some sort of a replace instead of the array_push()?

If it's not a good idea to modify an array while looping through it, could I simply check to see if an item exists. how would i check if the ['atags'] array for each switch contains a [tag] with a value that looks like "$attr_2_NNNN" where N is a number? For example, check out element 6 in the sample array above. The challenge is that it's not always element 6, and you're not always guaranteed that a tag will have the attr_2 value. I know there is an in_array() function ... i will try something like:

if (in_array(array('$attr_2_'), $switches['atags']))

I have a bug with the logic around the $nohardwareAttribFound variable, which i'm going to fix.
Thanks

Upvotes: 1

Views: 175

Answers (3)

huysentruitw
huysentruitw

Reputation: 28091

First of all: it is not advised to change an array or collection while you are iterating over it.

If you really want to do it like this, then you should take $switch by reference instead of by value. Otherwise you can change $switch to whatever you want, it will not be reflected in the $data['switches'] array.

To take $switch by reference just add the &:

foreach ($data['switches'] as &$switch) { 
}

Check out foreach in PHP manual.

EDIT After studying your code, I think this is what you are looking for:

foreach ($data['switches'] as &$switch) { 
    $hardwaremodel = array();
    $hardwaremodel['tag'] = NULL; // initialize to NULL so we can check at the end of the loop if we have found a hardwaremodel or not (so we don't need that bool)

    foreach ($switch['atags'] as $attributelist) { 
        foreach ($attributelist as $attribute) { 
            $pos = strpos(trim($attribute), '$attr_2_'); 
            if ($pos !== false) {
                $modelnumber = substr(trim($attribute), 8);
                $hardwaremodel['tag'] = 'hardware_model:' . $modelnumber;
                break;
            }
        }
        if ($hardwaremodel['tag'] !== NULL)
            break; // exit the loop because we already found a tag
    }

    if ($hardwaremodel['tag'] === NULL)
        $hardwaremodel['tag'] = 'hardware_model:unknown';

    // Note that this is a safe place to modify the $switch array
    // as we are not currently iterating it
    array_push($switch['atags'], $hardwaremodel); 
}

Upvotes: 1

Aleph
Aleph

Reputation: 1219

I think you should replace

foreach ($data['switches'] as $switch) 

with

foreach ($data['switches'] as &$switch) 

Using a reference should do.

Note: use unset($switch) afterwards to destroy the reference.

Upvotes: 0

prodigitalson
prodigitalson

Reputation: 60413

Everytime you enter the loop your interation variable (ie. $switch) is a copy - youre not modifying the original array $data. To do that you need to modify the full path like:

array_push($data['switches']['atags'], $newVal)

Or you can pass by reference when you enter the loop like:

foreach ($data['switches'] as &$switch) 
{
   // ... 
}

Upvotes: 0

Related Questions