php: Do not use array_filter() to delete empty elements of an array

Other language site
ja ja
Google Translate
  • -

    シェア
  • ---

    LINEで送る
  • -

    はてなブックマーク
    ブックマーク
  • -

    pocket
  • -

    rss
php logo

One way to remove empty elements from an array is to use array_filter (), array_values ().

However, you should definitely avoid using this method. I will explain the reason.

Reason should not to use array_filter(), array_values()

Let's see how to delete an empty element with array_filter(), array_values() before the reason which should not be used.

<?php

$array = [
    'data1',
    '',
    'data2',
    '',
    'data3',
    '',
    'data4',
    '',
    'data5',
];
$tmp = array_filter($array, 'strlen');
$array = array_values($tmp);

echo "Intermediate results:\n";
echo var_dump($tmp) . "\n\n";

echo "result:\n";
echo var_dump($array) . "\n\n";

The execution result looks like this.

Intermediate results:
array(5) {
  [0]=>
  string(5) "data1"
  [2]=>
  string(5) "data2"
  [4]=>
  string(5) "data3"
  [6]=>
  string(5) "data4"
  [8]=>
  string(5) "data5"
}


result:
array(5) {
  [0]=>
  string(5) "data1"
  [1]=>
  string(5) "data2"
  [2]=>
  string(5) "data3"
  [3]=>
  string(5) "data4"
  [4]=>
  string(5) "data5"
}

great! You got the results you intended.

This is done by executing strlen() on data of each array with array_filter(), and those returning 0 are deleted from the array.
Actually 0 is judged to be false and it is deleted. However, as it is, just deleting does not change the index of the array.

Use array_values () to refresh the index. You can do the intended processing with this.

However, at the development site, it often occurs that the type of data changes.
What happens if the data type of an array element is changed to an instance of classes or array?

Actually, there is a problem here.

What happens if an array or instance is included?

Let's run the sample program.

<?php

class TEST {
    private $property = 'property';
}

$array = [
    new TEST(),
    '',
    ['array1-1', 'array1-2', 'array1-3'],
    '',
];

$array = array_filter($array, 'strlen');
$array = array_values($array);

echo "result:\n";
echo var_dump($array) . "\n\n";

The execution result looks like this.

result:
array(0) {
}

Neither the array nor the instance of the class has disappeared.

This is a pretty bad situation. What happens when array_filter() is used in source code?

You have to investigate where the generated array data or class instance data has disappeared.
There may be people who check whether data is really being generated.
It consumes enormous time for this.

What do you think of the program that data will disappear just by slightly changing the data type? There is nothing good for everyone.

What's more troubling, versions prior to PHP 5.3, the array data did not disappear.
This is because if you specified an array with strlen (), it returned the string length of "Array" (5).
In PHP 5.3 and later, 0 is returned.

PHP documentation of strlen () is here

As you can see, array_filter(), array_values​​() is used more and more, it causes bugs.

Let's write the program obediently!

In such a case it is best to write a program obediently. It does not do difficult processing.
Let's see a sample program.

<?php

class TEST {
    private $property = 'property';
}

$array = [
    new TEST(),
    '',
    'data2',
    '',
    ['data3-1', '', 'data3-2', '', 'data3-3'],
    '',
    'data5',
];

function delete_empty_array($array) {
    $tmp;
    foreach($array as $item) {
        if( is_array($item) ) {
        	  $tmp[] = delete_empty_array($item);
        } else {
        	  if( ! empty($item)) {
        	      $tmp[] = $item;
        	  }
        }
    }
    return $tmp;
}

$array = delete_empty_array($array);

echo "result:\n";
echo var_dump($array);

The execution result looks like this.

result:
array(4) {
  [0]=>
  object(TEST)#1 (1) {
    ["property":"TEST":private]=>
    string(8) "property"
  }
  [1]=>
  string(5) "data2"
  [2]=>
  array(3) {
    [0]=>
    string(7) "data3-1"
    [1]=>
    string(7) "data3-2"
    [2]=>
    string(7) "data3-3"
  }
  [3]=>
  string(5) "data5"
}

Prepare a function delete_empty_array() which scans each piece of data and deletes empty elements.

If there is array data in this function, delete empty elements of all array data by calling delete_empty_array() recursively.
If it is not an empty element except array data, it will copy the data as it is.

This is just the end of the process. This is efficient because it is possible to erase the possibility of becoming a bug with just this work.

SNS also distributes articles.
Leave a Reply

*

If you like this article, share it!