0

Note: This is a question about a technical exercise. Please focus on utilising the same or similar array functions that I require instead of separating the code out into obviously more readable, but longer code segments.

I'm attempting to use an array_filter() and an array_walk() together. I haven't used these functions much, so I would like to learn about them in the process.

  • I have an array of possible environment strings ('sandbox', 'live', 'dev')
  • I have a string containing chosen environment ('dev')
  • I have an array of filepaths using glob()

I need to retrieve a list of files, using glob, that don't contain the strings from the difference between the two environments.

I have the following starting variables:

$possible = array('dev', 'sandbox', 'live');
$env = array('dev');

And obviously the difference between the two:

$diff = array_diff($possible, $env); // array('sandbox', 'live')

The directory I'm trying to perform a glob() on contains the following:

array(
    0 => '/config/dev.yml',
    1 => '/config/sandbox.yml',
    2 => '/config/live.yml',
    3 => '/config/global.yml',
    4 => '/config/routes.yml',
    5 => '/config/security.yml'
);

I would like to use array function calls to return the following:

array(
    0 => '/config/dev.yml', // Because $env = 'dev'. Sandbox and live are removed
    1 => '/config/global.yml',
    2 => '/config/routes.yml',
    3 => '/config/security.yml
);

Notice how sandbox.yml and live.yml have been removed.

Here is the code I'm using:

/** Loop through the list of yml files, placing $file into the local scope each time around, also import $possible, $env, $diff **/
$result = array_filter(glob(dirname(__DIR__) . '/config/*.yml'), function ($file) use ($possible, $env, $diff) {
    /** Loop around the diff (sandbox, live), placing them into $d each time around, also import $file again **/
    return array_walk($diff, function($d) use ($file) {
        /** Return when each environment (sandbox, live) is NOT in the $file string **/
        return !strstr($file, $d); 
    });
});

My issue is: Whatever the inner-most return changes to, it doesn't change the result. I can return true or false in there and it doesn't make a difference. I get back a list of all the files, *including the one's containing the string "sandbox.yml" and "live.yml", which isn't what I want.

Where is my logic going wrong?

2
  • array_walk: “Returns TRUE on success or FALSE on failure.” Since there is no “failure”, but walking through the array works successfully, you get TRUE returned every time, and that means array_filter will keep all array elements. (returning a value from inside the array_walk callback function does not work as you expect it to.) Commented Oct 8, 2013 at 10:31
  • @CBroe Ah so I'm using the wrong array method then. Can you suggest an alternative (in an answer, if you like) that achieves what I'm after? Another array_filter() perhaps? Commented Oct 8, 2013 at 10:32

1 Answer 1

1

The function array_walk() returns true on success which is almost every time you call it, so nothing gets filtered. You could consider a simple foreach inside instead:

$result = array_filter($files, function ($file) use ($diff) {
    foreach ($diff as $env) {
        if (strstr($file, $env) !== false) {
            return false;
        }
    }
    return true;
});

Alternatively, as mentioned by yourself:

$result = array_filter($files, function ($file) use ($diff) {
    return !in_array(basename($file, '.yml'), $diff);
});
Sign up to request clarification or add additional context in comments.

2 Comments

Jack's the repwhore today! :P Alternative is, instead of the foreach, return !in_array(basename($file, '.yml' ), $diff); apparently. Thanks :-)
@Jimbo Yes, I would have wanted to use array_some() here ;-)

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.