php 5.3 - PHP Bizarre behaviour with switch() and logical or (XOR) in a case declaration -


note: aware not acceptable code, seeking understand interpreter doing, not advice on how else achieve same result!

i've since read enough realize can't , shouldn't attempting use |,|| or xor in defining switch case—so please don't comment effect of "don't that", i'm trying understand interpreter doing such statements , understand strangeness of behavior. i'm using php 5.3.1.

this intending , using, please don't recommend code:

for ($i=0; $i<count($this->header); $i++) {             switch($i) {                 case 0:                     $this->header[ $i ] = $this->header[ $i ] ? $this->header[ $i ] : -5;   //angle goal                     break;                 case 1:                     $this->header[$i] = $this->header[$i] ? $this->header[$i] : -5;         //miss penalty                     break;                 case 2:                     $this->header[$i] = $this->header[$i] ? $this->header[$i] : -10;         //miss penalty                     break;                 case 3:                     $this->header[ $i ] = $this->header[ $i ] ? $this->header[ $i ] : -10;  //error penalty                     break;             }         } 

but got curious if do:

for ($i=0; $i<count($this->header); $i++) {             switch($i) {                 case 0 || 1:                     $this->header[ $i ] = $this->header[ $i ] ? $this->header[ $i ] : 15;   //angle goal                     break;                 case 2 || 3:                     $this->header[$i] = $this->header[$i] ? $this->header[$i] : -5;         //miss penalty                     break;             }         } 

and, perversely, run, very (like, seconds), , though of course evaluates (0||1) not @ way i'd intended (and indeed today lesson on difference between bitwise , logical operators).

but more curious me fact this, if , not results i'd wanted:

for ($i=0; $i<count($this->header); $i++) {             switch($i) {                 case 0 xor 1:                     $this->header[ $i ] = $this->header[ $i ] ? $this->header[ $i ] : 15;   //angle goal                     break;                 case 2:                     $this->header[$i] = $this->header[$i] ? $this->header[$i] : -5;         //miss penalty                     break;                 case 3:                     $this->header[$i] = $this->header[$i] ? $this->header[$i] : -5;         //miss penalty                     break;             }         } 

but not this:

for ($i=0; $i<count($this->header); $i++) {             switch($i) {                 case 0 xor 1:                     $this->header[ $i ] = $this->header[ $i ] ? $this->header[ $i ] : 15;   //angle goal                     break;                 case 2 xor 3:                     $this->header[$i] = $this->header[$i] ? $this->header[$i] : -5;         //miss penalty                     break;             }         } 

this 1 of these terrible, terrible ideas php wouldn't evaluate.

my question is: why evaluating these statements take so, longer, , why last example not run? considered php interpreting 0 xor 1 , comparing true , false, couldn't substitute in , have still evaluate. know what's happening here? thanks!


update:

comments requested var_dump($this->header) (in case isn't obvious, truncated initial switch statement 7 cases 4 avoid spamming lines of identical code, but, given var_dump() requested, chose post whole thing in case revealed couldn't forsee!). also, yes, turns out i'd been using associative array due forgetting have called array_values() before setting $this->header, in second answer below, having made error turns out explain duration of switch statement, whilst first answer , second answer great walkthroughs of logic.

array(12) {   ["thezone"]=>   null   ["leftmiss"]=>   null   ["rightmiss"]=>   null   ["lefterror"]=>   null   ["righterror"]=>   null   ["lefthit"]=>   null   ["righthit"]=>   null   ["accuracy"]=>   string(5) "false"   ["rt"]=>   string(4) "true"   ["disease"]=>   string(3) "yes"   ["bars"]=>   string(3) "yes"   ["endmessage"]=>   null } 

case values have single values. can't 2 || 3, because that'll evaluate as

case (2 or 3) -> case true 

similarly, if using && (and), you'd get

case (0 , 1) -> case false 

you can use 'fallthrough' behavior or logic:

case 2: case 3:    ...code here ...    break; 

xor, can't do. not simple case statement.

comment followup:

for ($i = 0; $i < 5; $i++) {    switch($i) {        case 0 xor 1:  echo "0 xor 1: $i\n"; break;        case 2 xor 3:  echo "2 xor 3: $i\n"; break;    } } 

will output

2x3: 0 0x1: 1 0x1: 2 0x1: 3 0x1: 4 

and

php > var_dump(2 xor 3); bool(false) php > var_dump(0 xor 1); bool(true) 

remember switch cases evaluate same ==. they're lazy comparisons, not checking types. 2 xor 3 evaluated same if case has been case false, makes $i=0 condition match.


Comments