3

This has boggled me for a while. I am running through a directory and echo'ing out its contents, and I want to exclude the ".." and "." files.

Now, this code works:

if ($files = scandir("temp/"))
{
    foreach ($files as $file)
    {
        if ($file == ".." OR $file == ".")
        {
        }
        else {
            echo $file;
            echo "<br>";
        }
    }
}

But this doesn't...

if ($files = scandir("temp/"))
{
    foreach ($files as $file)
    {
        if ($file != ".." OR $file != ".")
        {
            echo $file;
            echo "<br>";
        }
    }
}

For obvious reasons the second lump of code is more what I want, because I really hate having the true statement do nothing.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Whitey
  • 153
  • 2
  • 5

7 Answers7

22

If you negate a condition consisting of two single conditions and a conjunction ("and" or "or"), you need to negate each condition separately and use the other conjunction.

So try this instead:

if ($file != ".." AND $file != ".")
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Franz
  • 11,353
  • 8
  • 48
  • 70
9

This is one of deMorgan's Laws.

not (A OR B) = (not A) AND (not B)

The change you are making is a refactoring called Reverse Conditional

Ewan Todd
  • 7,315
  • 26
  • 33
4

They're not opposites...

Check out de Morgan's laws.

if($file != ".." OR $file != ".")

should be

if($file != ".." AND $file != ".")
Austin Salonen
  • 49,173
  • 15
  • 109
  • 139
2

You have to negate the entire expression, just like -(-x + 2) in math negates everything:

if ($file == ".." OR $file == ".")

Is not the negation of

if ($file != ".." OR $file != ".")

Because you didn't negate the OR. The opposite of OR is AND, resulting a:

if ($file != ".." AND $file != ".")
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
LiraNuna
  • 64,916
  • 15
  • 117
  • 140
2

$file != ".." evaluates to true. Instead, simply use an AND operator:

if ( $file != '..' && $file != '.' ) { }

However, I would use DirectoryIterator instead:

foreach (new DirectoryIterator('temp') as $fileInfo) {
    if ($fileInfo->isDot())
        continue;
    echo $fileInfo->getFilename() . "<br>\n";
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
meder omuraliev
  • 183,342
  • 71
  • 393
  • 434
1

This:

    if ($file != ".." OR $file != ".")

should be:

    if ($file != ".." && $file != ".")
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
schneck
  • 10,556
  • 11
  • 49
  • 74
1

Alternatively, you could always use DirectoryIterator and specifically its isDot method.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Peter Bailey
  • 105,256
  • 31
  • 182
  • 206