14

I got this multiple array named $files[], which consists of keys and values as below:

[
    [
        'name' => 'index1.php',
        'path' => 'http://localhost/php/gettingstarted/',
        'number' => 1,
    ],
    [
        'name' => 'index10.php',
        'path' => 'http://localhost/php/gettingstarted/',
        'number' => 2,
    ],
    [
        'name' => 'index11.php',
        'path' => 'http://localhost/php/gettingstarted/',
        'number' => 3,
    ],
]

I use this code to create a new array consist of 'name' keys only. But it failed

array_filter($files, "is_inarr_key('name')");

function is_inarr_key($array, $key)
{
    //TODO : remove every array except those who got the same $key
}

and I get this error:

array_filter() [function.array-filter]: The second argument, 'is_inarr_key('name')', should be a valid callback in C:\xampp\htdocs\php\gettingstarted\index.php on line 15

So my questions are:

  1. Is it possible to make the call-back function on array_filter receive parameter?
  2. What is the general rule of thumb on how to use callback in any PHP built-in function?
1
  • This question is Unclear about the actual required filtering logic. Can we have a minimal reproducible example please? Are you retaining rows which have a key called name or are you filtering rows which contain a specific value in the name column or are you wanting to isolate the values in the name column as a new array? That I use this code to create a new array consist of 'name' keys only. sentence makes me believe it is the third one. In which case, you don't need array_filter(), you want array_column(). This question may be an XY Problem. Commented Dec 15, 2023 at 10:48

5 Answers 5

44

You can create a closure on PHP ≥5.3.

array_filter($files, function($array) use ($key) {
  return is_inarr_key($array, $key); 
} );

If you are stuck with PHP <5.3, …

You can make $key a global variable.

function is_inarr_with_global_key($array) {
   global $key;
   ....
}

You can create a class

class KeyFilter {
  function KeyFilter($key) { $this->key = $key; }
  function is_inarr_key($array) { ... }
}
...
array_filter($files, array(new KeyFilter('name'), 'is_inarr_key'));

You can create 3 different functions

array_filter($files, 'is_inarr_name');
array_filter($files, 'is_inarr_path');
array_filter($files, 'is_inarr_number');

You can write your own array_filter

function my_array_filter($files, $key) {
  ...
}
Sign up to request clarification or add additional context in comments.

2 Comments

i haven't try it. but this solution's brilyan. if i convert my code work with closure or class, i will able to work with more keys AND create ONLY one fun ction : is_inarr_key()
+1, but if it were my answer I would list the closure-based solution first and recommend it over the alternatives. It's the simplest and shortest of the possibilities by far.
2

You can make use of the array_walk function as:

$arr = array(
        array("name" => "Jack", "id" => 1),
        array("name" => "Rose", "id" => 2),
    );

$result = array(); // initialize result array.
array_walk($arr, "filter"); // iterate over the array calling filter fun for each value.
// $result will now have elements "Jack" and "Rose"

function filter($a) {

    global $result; // to access the global result array.

    $result[] = $a['name']; // for each array passed, save the value for the key 'name' in the result array.
}

Comments

1

I am unaware if you can supply the callback function with parameters, but as a suggestion, you could define a callback function for array_filter

array_filter($files, "is_inarr_key");

And to get the name of the array, just loop over the $file[] and retrieve the name. Then, having the name you can go on with your logic.

HTH.

Comments

1

You can use create_function() in 5.2.x

$y = 5;
$func = 'return $x > ' . $y . ';';
$f = create_function('$x', $func);
$numbers = range(0, 10);
$result = array_filter($numbers, $f);
print_r($result);

which outputs

Array ( [6] => 6 [7] => 7 [8] => 8 [9] => 9 [10] => 10 )

Comments

1

thanks KennyTM for keyfilter class great tip. For those who care and don't know how to do it, this a working detailed example. I slightly improved using a regexp pattern.

$files[]= {code above};

class KeyFilter {
    function KeyFilter($attr,$pattern)
    {
        $this->attr=$attr;
        $this->pattern=$pattern;
    }
    function is_inarr_key($t)
    {
        return preg_match($this->pattern,$t[$this->attr]);;
    }
}


$t=array_filter($items, array(new KeyFilter("path","~\d{2}\.php~i"), 'is_inarr_key'));
print_r($t);
print_r($o->key);

output:

[1] => Array
(
    [name] => index**10**.php
    [path] => http://localhost/php/gettingstarted/
    [number] => 2
)

[2] => Array
(
    [name] => index**11**.php
    [path] => http://localhost/php/gettingstarted/
    [number] => 3
)

Comments

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.