Casey Dwayne
Casey Dwayne

Reputation: 2169

PHP or/xor operator isn't working like expected

/* Create Theme Rules */
if($selectedTheme=='spring' or 'framed' or 'art' or 'champagne'){
  echo 'yes';
}

I have this scripting that should only take place if the $selectedTheme equals one of the above, but it does it on every theme. This works fine:

  if(
    ($selectedTheme==('spring') or 
    ($selectedTheme==('framed')) or 
    ($selectedTheme==('art')) or 
    ($selectedTheme==('champagne')))
   )
     { echo 'yes'; }

But that seems like a lot of unnecessary code. What am I misunderstanding here?

Upvotes: 0

Views: 151

Answers (3)

Mateusz Kubuszok
Mateusz Kubuszok

Reputation: 27595

Look at evaluation of:

($selectedTheme==('spring') or 
($selectedTheme==('framed')) or 
($selectedTheme==('art')) or 
($selectedTheme==('champagne')))

It does actually:

  1. compare $selectedTheme to 'spring', if its true whole expression is true, otherwise

  2. compare $selectedTheme to 'framed' - if its true whole expression is true, otherwise,

  3. compare $selectedTheme to 'art', if its true whole expression is true, otherwise

  4. compare $selectedTheme to 'champagne' - if its true whole expression is true, otherwise, expression is false,

while:

 ($selectedTheme=='spring' or 'framed' or 'art' or 'champagne')

does:

  1. compare $selectedTheme to 'spring', if its true whole expression is true, otherwise,

  2. if 'framed' is true return true - non-empty string is resolved as true when used as boolean, thus whole expression is always true.

As a result Your former code is always true, while the latter works as You expect. Programming languages are kind of strict and You shouldn't rely on mental leaps unless language's definition openly allow it. Shorter replacement was presented by @bwoebi.

Upvotes: 1

Mark Reed
Mark Reed

Reputation: 95395

Your expression:

if ($selectedTheme == 'spring' or 'framed' or 'art' or 'champagne')

is using an interpretation of English or that is shared by relatively few programming languages. The arguments to or are usually independent, so the above is asking if either the selected theme is equal to 'spring', or the string 'framed' is (of its own accord) true, or the string 'art' is true, or the string 'champagne' is true. Since any non-empty string is true in PHP, the expression as a whole is always true.

There are lots of ways to avoid the repetition of the longer-form if; the simplest is probably in_array, as @bwoebi suggested.

Upvotes: 1

bwoebi
bwoebi

Reputation: 23787

The above you cannot do; it simply evaluates as $selectedTheme=='spring' or true or true or true.

A shorter, less redundant version would be:

if (in_array($selectedTheme, ['spring', 'framed', 'art', 'champagne'])) // PHP 5.4 syntax (use array(...) if you have PHP 5.3 or lower)

You also could use a switch with no breaks and a lot of cases:

switch ($selectedTheme) {
    case 'spring':
    case 'framed':
    case 'art':
    case 'champagne':
        // do something
}

Upvotes: 2

Related Questions