2010-12-21 12 views
6

Poniższy przykład jest wyciąg z http://php.net/manual/de/control-structures.switch.phpproblem z przełącznikiem warunkowego

<?php 
$totaltime = 0; 
switch ($totaltime) { 

    case ($totaltime < 1): 
     echo "That was fast!"; 
     break; 

    case ($totaltime > 1): 
     echo "Not fast!"; 
     break; 

    case ($totaltime > 10): 
     echo "That's slooooow"; 
     break; 
} 

?> 

Spodziewałem wynik jako „To był szybki.” Ale rzeczywisty wynik to "Nie szybko!". Byłoby wspaniale, gdyby ktoś mógł mi wyjaśnić, dlaczego?

Ale jeśli dodaję kolejny przypadek, case 0: echo "That was super fast!". To echo jest prawidłowo. "To było super szybkie!". Proszę mi pomóc, jak użyć warunkowego oświadczenia przełącznika.

EDIT: -

Dzięki wszystkim za odpowiedzi. Jestem w stanie przezwyciężyć powyższy problem przez modifyong switch ($ totalTime), aby przełączyć (1)

+0

= Wyłącznik ocenić tylko raz, wydaje mis-used na nim – ajreal

Odpowiedz

10

case ($totaltime < 1): oznacza 1 do PHP (czyli równanie zwraca true)

case ($totaltime > 1): oznacza 0 do PHP (czyli równanie zwraca false)

od $totaltime jest 0, można dostać się, że wyświetlamy

innymi słowy PHP porównuje $totaltime do wyniku porównań.

EDIT dotyczące edycji w OP:

Musisz pozbyć się switch() -statement. Używasz go tylko do łatwego porównywania różnych wartości i używania z nim dodatkowych wyrażeń.

mam na myśli to, co jest nie tak z

<?php 
$totaltime = 0; 

if ($totaltime < 1) { 
    echo "That was fast!"; 
} else if ($totaltime > 10) { 
    echo "That's slooooow"; 
} else if ($totaltime > 1) { 
    echo "Not fast!"; 
} 

?> 

EDIT: należy pamiętać, że przeszedłem dwa ostatnie IF-deklaracje, aby to naprawdę działa.

+0

- Nie ma żadnych błędów. Ale mam blisko 20 wartości, dla których muszę porównać i wyświetlić błąd. Tak więc myślałem, że przełącznik sprawi, że będzie on bardziej czytelny niż IF. – satya

+0

@lucky: ale rozumiesz, że jest on dużo bardziej czytelny dzięki zestawowi instrukcji 'if()'? Oznaczałoby to również mniej kodu, co skutkuje mniejszymi szansami na błąd (to raczej ogólna zasada). – sjngm

1

Wygląda na to, że jest to problem z konwersją binarną.

Pierwsze stwierdzenie przypadku będzie oceniane jako cokolwiek innego niż 0, aby nie trafiło.

Ale druga instrukcja case będzie oceniała wartość false, która powinna wynosić 0, co jest równe ustawieniu $ totaltime na.

1

Szczęście,

Przełącznik PHP jest taki sam jak seria instrukcji IF. Przypadki są oceniane jako:

if($totaltime == ($totaltime < 1)) { 
    echo "That was fast!"; 
    break; 
} 
if($totaltime == ($totaltime > 1)) { 
    echo "Not fast!"; 
    break; 
} 
... 

Wyraźnie 0 == false dla 2. Jeżeli prawdą i stąd wynik.

Dzięki, Vikas.

2

Nie używaj warunków w instrukcjach case, ale nie intuicyjnie. To, co się dzieje:

case ($totaltime < 1): // Evaluates to 1. $totaltime is not 1, so no match. 
    case ($totaltime > 1): // Evaluates to 0. $totaltime is 0, so match. 

Zasadniczo próbujesz użyć else if konstrukt jako switch konstruktu, ale funkcjonalność nie ma.Warianty nie oceniają w sposób, jakiego oczekujesz (tak jak w bloku if), szukają tylko pierwszego bloku, który jest równy wartości testowanej w bloku switch.

0

Inni wspomnieli, dlaczego tak się dzieje (niewłaściwe użycie warunku w przypadku sprawy), ale nie oferowali alternatyw. Przełącznik ma na celu objęcie określonych argumentów, takich jak {0, 1, 2, 3..100, 101} itp. Oddziela on określone argumenty lub zakresy zamiast wykonywania prostego if/else (tak jak go używałeś). Można przepisać swoje argumenty, aby wyciągnąć go jednak:

switch ($totaltime) { 

    case (0): 
     echo "That was fast!"; 
     break; 

    case (1..PHP_INT_MAX): 
     echo "Not fast!"; 
     break; 

    default: 
     echo "That's slooooow"; 
     break; 
} 

Tu .. umożliwia zasięg mają być objęte, więc coś od 1 do liczby całkowitej max jest objęta tym przypadku. 0 jest obsługiwane jawnie, a wszystkie inne (re: < 0) są objęte domyślnym przypadkiem.

+0

+1, Thanku za odpowiedź. Tego właśnie szukam. gdy $ totaltime = 10; to powoduje "To jest slooooow"; zamiast "Nie szybko!"; – satya

+0

-1 PHP nie obsługuje zakresów takich jak w przełączniku/obudowie. Twoja 'case (1..PHP_INT_MAX):' zwraca zwartą wartość 1 i PHP_INT_MAX (12147483647). Wydaje mi się, że ostatnio zrobiłeś za dużo Pascala i mieszałeś składnię PHP i Pascala: p. – wimvds

+0

@wimvds: Dzięki za komentarz i informacje. Wydaje mi się, że ostatnio ostatnio spędzałem zbyt wiele czasu w innych językach. –

2

Nienawidzę na necro postu, na który już udzielono odpowiedzi, ale jestem raczej zaskoczony, nikt nie dotknął metody przełącznika (true).

Nie ma prawdziwego świata zaletą prędkość każdej z metod

W niektórych przypadkach przełącznik był szybszy, inni if ​​było szybciej, ale tylko przez ułamki mikrosekundy (48.16 ms vs 49.11 ms przełączać szybciej niż jeśli).

EDIT

A teraz widzę PO zrobił to samo ...

<?php 
for ($totaltime = 0; $totaltime < 11; $totaltime += 0.5) { 
    switch (true) { 
     case ($totaltime < 1): 
      echo $totaltime . " That was fast!\n"; 
      break; 
     case ($totaltime < 10): 
      echo $totaltime . " Not fast!\n"; 
      break; 
     default: 
      echo $totaltime . " That's slooooow\n"; 
      break; 
    } 
} 

Wyniki: https://3v4l.org/d71lZ

0 That was fast! 
0.5 That was fast! 
1 Not fast! 
1.5 Not fast! 
2 Not fast! 
2.5 Not fast! 
3 Not fast! 
3.5 Not fast! 
4 Not fast! 
4.5 Not fast! 
5 Not fast! 
5.5 Not fast! 
6 Not fast! 
6.5 Not fast! 
7 Not fast! 
7.5 Not fast! 
8 Not fast! 
8.5 Not fast! 
9 Not fast! 
9.5 Not fast! 
10 That's slooooow 
10.5 That's slooooow 
Powiązane problemy