user3791372
user3791372

Reputation: 4665

array_walk trying to write to outside array

I have a simple piece of code that isn't working as I would expect it would, could someone please explain why it isn't populating the fields array and how to solve it.

$fields = [];

array_walk($class->properties, function($v, $k) use ($fields) {
    $fields[] = $v->name;
});

die(var_dump($fields));

// output is []

Upvotes: 3

Views: 1809

Answers (3)

slevy1
slevy1

Reputation: 3832

The following code demonstrates a class whose sole property properties contains an array of objects, each of which has a name property, as follows:

<?php

$class = new stdClass;
$class->properties = [new stdClass,new stdClass, new stdClass];

$class->properties[0]->name = "Anne";
$class->properties[1]->name = "Bob";
$class->properties[2]->name = "Robin";

$fieldsA = [];
$fieldsB = [];

if ( array_walk( $class->properties, function( $o ) use ( &$fieldsA ){ 
                                      $fieldsA[] = $o->name;
                                    }) ) {
   echo "\nMission accomplished:\n";
   var_dump($fieldsA);
}

$fieldsB = array_map(  function( $e ) {
                                      return $e->name;
                                      },$class->properties);
if (count($fieldsB) > 0) {
   echo "\nMission accomplished:\n";
   var_dump( $fieldsB );
}

See live code

As you may note, both array_walk() and array_map() will produce the same results of stuffing a new array with the names that the three objects contain. Array_map() offers more simplicity than array_walk() which requires a use variable and a reference operator. Also, the return value of array_map() is a brand new array if all goes well. So, I concur with @localheinz and recommend it as the better choice.

Note: regarding the callback, it is unnecessary to specify value, key parameters. Both of these built-in functions examine each element of properties. Specifying function( $v, $k ) would be helpful if the code needed to do something with an element's key.

Upvotes: 0

localheinz
localheinz

Reputation: 9582

Alternatively, you can use array_map():

$fields = array_map(function($v) {
    return $v->name;
}, $class->properties);

die(var_dump($fields));

For reference, see:

Upvotes: 1

Felippe Duarte
Felippe Duarte

Reputation: 15131

Use this:

$fields = [];

array_walk($class->properties, function($v, $k) use (&$fields) {
    $fields[] = $v->name;
});

die(var_dump($fields));

After I wrote this I saw Mark Baker comment. That's the right answer.

For reference, see:

Upvotes: 5

Related Questions