Search code examples
phparraysunset

PHP unset() selectively working


I know there's a lot of these unset() problems on here, but this one is different. I'm trying to create an array that is a partial listing of a directory, with file names ".", "..", "feed.txt", and "index.php" removed. Here's the code:

var_dump($posts);
echo "this is arrayElementIsString(posts, file) before ->" . arrayElementIsString($posts, "index.php") . "<-
";
foreach($posts as $file) {
    if($file == "." || $file == ".." || $file == "feed.txt" || $file == "index.php") {
        unset($posts[arrayElementIsString($posts, $file)]);
    }
}

echo "this is arrayElementIsString(posts, file) after ->" . arrayElementIsString($posts, "index.php") . "<-
";
var_dump($posts);

arrayElementIsString() is a function I wrote. It searches an array for a particular string and returns the index of that array element. Here it is:

function arrayElementIsString($array, $searchString) {
    for($i=0; $i < count($array); $i++) {
        if((string)$array[$i] == $searchString) {
            return $i;
        }
    }
}

Here is the output from this code:

    array(6) {
  [0]=>
  string(1) "."
  [1]=>
  string(2) ".."
  [2]=>
  string(20) "another-new-post.php"
  [3]=>
  string(8) "feed.txt"
  [4]=>
  string(9) "index.php"
  [5]=>
  string(17) "new-test-post.php"
}
this is arrayElementIsString(posts, file) before ->4<-
    this is arrayElementIsString(posts, file) after -><-
    array(3) {
  [2]=>
  string(20) "another-new-post.php"
  [4]=>
  string(9) "index.php"
  [5]=>
  string(17) "new-test-post.php"
}

The first var_dump shows the complete directory listing, the first in between line shows the index of "index.php", the next line shows the value having been unset, and the second var_dump shows "index.php" in the array still.

What I don't get is why this works for ., .., and feed.txt, but index.php is still listed after clearly being unset. I've tried moving the index.php file to the middle of the if statement to see if it would instead not unset one of the other files, but that didn't effect anything


Solution

  • Removing elements in an array inside a foreach-loop is a bad idea. Therefor you should instead setup a new array and do the following:

    $newArray = array();
    foreach($posts as $file) {
        if($file == "." || $file == ".." || $file == "feed.txt" || $file == "index.php") {
            continue;
        }
        $newArray[] = $file;
    }