0

I was looking at the WooCommerce code base and I found this code

'product_ids' => isset( $_POST['product_ids'] ) ? array_filter( array_map( 'intval', (array) $_POST['product_ids'] ) ) : array()

I can see that a POST value is being parsed into an array and that only integer values are being included but I'm wondering why array_filter and array_map are being used, wouldn't

‌‌isset( $_POST['product_ids'] ) ? array_filter( (array) $_POST['product_ids'], 'intval'  ) : array()

return the same result?

I was wondering if there is an edge case/best practice that I'm missing?

ipr101
  • 24,096
  • 8
  • 59
  • 61
  • I don't think that this is a duplicate as neither of the questions listed provides an answer to my question. I would be interested in how I can apply the knowledge in those questions to answer the question I ask in the last line of this question. – ipr101 Oct 04 '20 at 08:07
  • It's a shame that it's possible to close a question anonymously without providing any other detail than here are a couple of questions I've found that include some words from your question in their title. – ipr101 Oct 04 '20 at 08:15
  • Also, it seems strange to ask me to post a new question if neither of the suggested questions answers my current question. What's my motivation to do that? Presumably, someone will just come along and anonymously close the new question as words from it will match titles of other existing questions. It's like saying you've been found wrong for unspecified reasons, please try again in the hope that you won't be found wrong again for further unspecified reasons. – ipr101 Oct 04 '20 at 08:22

1 Answers1

3

There would be no difference at all if you use the second one as a replacement of first one.

Why: This is due to behaviour of intval function.

intval Returns integer value of variable on success, or 0 on failure. Empty arrays return 0, non-empty arrays return 1.

Point to be noticed: 0 is considered as false, and any other non-zero integer value considered as true in PHP.

array_filter filters data based on return value of callable function which should be either true of false.

Now in your situation you're calling array_filter in two manners.

array_filter( array_map( 'intval', (array) $_POST['product_ids'] ) )

  • In this you're passing an array of integers to array_filter as array_map will loop over array and convert each value to corresponding integer by calling intval function.
  • Now as there is no parameter passed in array_filter so by default empty function will be used and only numeric but not zero(0) values remains.

array_filter( (array) $_POST['product_ids'], 'intval' )

  • In this you are calling array_filter but intval as callable function, which will convert each value to corresponding integer. Main catch is here, if corresponding value is 0 then it will be false, otherwise true, which is equivalent to empty function in this case.

Note: This doesn't apply to other functions and would not create same results. See this by comparing intval and is_string function.

// Input data
$entry = [
    0 => 'foo',
    1 => false,
    2 => -1,
    3 => null,
    4 => '',
    5 => '0',
    6 => 0,
];

// comparison for intval function
print_r(array_filter( array_map( 'intval', $entry ) ));
print_r(array_filter( $entry, 'intval'  ));

Output:
Array
(
    [2] => -1
)
Array
(
    [2] => -1
)

// but if you try another function like is_string
print_r(array_filter( array_map( 'is_string', $entry ) ));
print_r(array_filter( $entry, 'is_string'  ));
Output:
Array
(
    [0] => 1
    [4] => 1
    [5] => 1
)
Array
(
    [0] => foo
    [4] => 
    [5] => 0
)
Dark Knight
  • 6,116
  • 1
  • 15
  • 37