5

I know this is simple PHP logic but it just won't work...

 $str = "dan";
 if(($str != "joe") 
   || ($str != "danielle")
   || ($str != "heather")
   || ($str != "laurie")
   || ($str != "dan")){         

 echo "<a href='/about/".$str.".php'>Get to know ".get_the_author_meta('first_name')." &rarr;</a>";
                  }

What am I doing wrong?

Bridge
  • 29,818
  • 9
  • 60
  • 82
Greg Thompson
  • 886
  • 4
  • 12
  • 31
  • 7
    What do you expect to happen?Please,describe. –  Jun 10 '11 at 19:15
  • Also,your variable is set to `dan` and you check if the variable isn't dan (or other) and echo something.I think that you expect to see the info ,outputed with echo but your variable is `dan`. –  Jun 10 '11 at 19:18
  • 2
    To be honest, it seems like you want `==` instead of `!=` ... – joakimdahlstrom Jun 10 '11 at 19:20
  • 8
    Also you probably should be using `in_array()` here. – mario Jun 10 '11 at 19:21

6 Answers6

42

I am not exactly sure what you want, but that logic will always evaluate to true. You might want to use AND (&&), instead of OR (||)

The furthest statement that is ever tested is ($str != "danielle") and there are only two possible outcomes as PHP enters the block as soon as a statement yields true.

This is the first:

$str = "dan";

$str != "joe" # true - enter block
$str != "danielle" #ignored
$str != "heather" #ignored
$str != "laurie" #ignored
$str != "dan" #ignored

This is the second:

$str = "joe";

$str != "joe" # false - continue evaluating
$str != "danielle" # true - enter block
$str != "heather" #ignored
$str != "laurie" #ignored
$str != "dan" #ignored

If the OR was changed to AND then it keeps evaluating until a false is returned:

$str = "dan";

$str != "joe" # true - keep evaluating
$str != "danielle" # true - keep evaluating
$str != "heather"  # true - keep evaluating
$str != "laurie" # true - keep evaluating
$str != "dan"  # false - do not enter block

The solution doesn't scale well though, you should keep an array of the exclude list and check against that do:

$str = "dan";
$exclude_list = array("joe","danielle","heather","laurie","dan")
if(!in_array($str, $exclude_list)){          
    echo " <a href='/about/".$str.".php'>Get to know ".get_the_author_meta('first_name')." &rarr;</a>";
}
Cullub
  • 2,901
  • 3
  • 30
  • 47
Gazler
  • 83,029
  • 18
  • 279
  • 245
  • just curious, but wouldn't && mean that they all must be right? basically the full function will get the authors name and only do that for certain authors not named above... – Greg Thompson Jun 10 '11 at 19:16
  • 2
    Yeah, so you want to return if the **$str is not equal to "joe" and $str is not equal to "danielle" $str is not equal to "heather"** etc. – Gazler Jun 10 '11 at 19:18
  • "Right" for != means that it's not one of the named authors. – Amber Jun 10 '11 at 19:19
  • != means NOT EQUAL so if when you say $str != "joe", you actually say (is $str(dan) different from joe? wich is TRUE) so its continue evaluating and ignore the rest.. – Patrick R Jun 10 '11 at 19:33
  • 8
    @Gazler Congrats on the Reversal badge :-) – Bridge Aug 16 '13 at 12:08
  • 1
    @Gazler according to http://stackoverflow.com/questions/2473989/list-of-big-o-for-php-functions in_array also scales O(n). Using array('key' => true); and !isset($exclude_list[$key]) scales O(1) or O(ln(n)). Great answer anyway! – Christoph Diegelmann Aug 21 '13 at 09:20
11

Another approach is

$name = 'dan';
$names = array('joe', 'danielle', 'heather', 'laurie', 'dan');

if(in_array($name,$names)){  
    //the magic
}
joakimdahlstrom
  • 1,575
  • 1
  • 11
  • 23
8

Welcome to boolean logic:

$str = 'dan'

$str != "joe" -> TRUE, dan is not joe
$str != "danielle" -> TRUE, danielle is not dan
$str != "heather") -> TRUE, heather is not dan
$str != "laurie" -> TRUE, laurie is not dan
$str != "dan" -> FALSE, dan is dan

Boolean logic truth tables look like this:

and:

TRUE && TRUE -> TRUE
TRUE && FALSE -> FALSE
FALSE && FALSE -> FALSE
FALSE && TRUE -> FALSE

or:

TRUE || TRUE -> TRUE
TRUE || FALSE -> TRUE
FALSE || TRUE -> TRUE
FALSE || FALSE -> FALSE

Your statement boiled down to:

TRUE || TRUE || TRUE || TRUE || FALSE -> TRUE
Marc B
  • 356,200
  • 43
  • 426
  • 500
6

Based on your comment in Glazer's answer, it looks like you want to enter the if block when $str is not one of the listed names.

In that case it would be more readable if you write it as

if( !( ($str == "joe") || ($str == "danielle") || ($str == "heather") || ($str == "laurie") || ($str == "dan") ) )

This actually reads as "if it's not one of these people..." to someone looking at your code. Which is equivalent to the slightly less obvious

if( ($str != "joe") && ($str != "danielle") && ($str != "heather") && ($str != "laurie") && ($str != "dan") )

The fact that they're equivalent is called DeMorgan's law in logic.

trutheality
  • 23,114
  • 6
  • 54
  • 68
2

try this

$str = "dan";

if($str == "joe" || $str == "daniella" || $str == "heather" || $str == "laurine" || $str == "dan"){ ... }
Patrick R
  • 1,949
  • 3
  • 32
  • 58
0

When you compare two strings you have to use strcmp().