Verwendung von Vergleichsoperatoren in einer PHP-‘switch’-Anweisung

Lesezeit: 6 Minuten

Benutzer-Avatar
Jessie Stiel

Ich habe vier Bedingungen, die ich durchlaufen muss, und ich dachte, es wäre am besten, die zu verwenden switch Anweisung in PHP. Ich muss jedoch prüfen, ob eine ganze Zahl beispielsweise kleiner oder gleich oder größer und gleich ist.

switch ($count) {
    case 20:
        $priority = 'low';
        break;

    case 40:
        $priority = 'medium';
        break;

    case 60:
        $priority = 'high';
        break;

    case 80:
        $priority = 'severe';
        break;
}

Mit einem if() Anweisung würde es wie folgt aussehen:

if ($count <= 20) {
    $priority = 'low';
} elseif ($count <= 40) {
    $priority = 'medium';
} elseif ($count <= 60) {
    $priority = 'high';
} else {
    $priority = 'severe';
}

Ist das drin möglich switch-case?

  • Ja, du kannst switch(true) und in den Fällen, die den Bereich Example erfüllen, true zurückgeben. Wenn dies in einem kleineren Maßstab wäre, könnten Sie einfach die Zahlen im Bereich wiederholen und sie ineinander fließen lassen. Beispiel. Aber ja, für Ihr Beispiel sollten Sie eine if-Anweisung verwenden.

    – David Chen

    17. Juli 2014 um 20:26 Uhr


  • @DaveChen Das ist ein netter Trick.

    – Havenar

    17. Juli 2014 um 20:41 Uhr

  • Demnach können Sie anscheinend — nach (Randomizer) suchen — php.net/manual/en/control-structures.switch.php

    – Tasos

    17. Juli 2014 um 20:43 Uhr

Ein allgemeinerer Fall zur Lösung dieses Problems ist:

switch (true) {
    case $count <= 20:
        $priority = 'low';
        break;

    case $count <= 40:
        $priority = 'medium';
        break;

    case $count <= 60:
        $priority = 'high';
        break;

    default:
        $priority = 'severe';
        break;
}

  • Der GANZE Grund (der einzige Grund, IMO) für die Verwendung eines Skript-Bloating-Switch-Blocks besteht darin, eine einzige Auswertung eines Werts durchzuführen und die zufriedenstellenden Fälle zu finden. Diese “Lösung” verzichtet auf diesen Vorteil, indem mehrere Auswertungen zur Genüge durchgeführt werden truealso ist es genauso ineffizient wie ein if-elseif-else Block, aber mit viel mehr Code-Bloat. Ich empfehle so etwas wie Havenards berechnete Suche, es ist prägnant, einfach zu warten, effizient und hochgradig skalierbar.

    – mickmackusa

    10. Oktober 2019 um 13:44 Uhr


  • Die andere Lösung gilt nur, wenn Reichweiten vorberechnet werden können. Diese Lösung ist perfekt für Bereiche, die willkürlich gewählt werden. Stellen Sie sich einen Datums-Zeit-Unterschied in Sekunden vor und Sie geben Blöcke wie „vor mehr als 1 Jahr“, „vor mehr als 1 Monat“, „vor ein paar Tagen“, „gestern“, „vor ein paar Stunden“, „ein paar vor Minuten”, “vor ein paar Sekunden”, “gerade jetzt”. Dies erfordert die in dieser Antwort angegebene Lösung.

    – Xavi Montero

    31. Juli 2021 um 15:28 Uhr

  • Außerdem: Was ist ein Schalter anders als eine Kette von if-elses, bei der der erste Ausdruck der Gleichheit konstant bleibt? Ein Klassiker switch( $a ){ case 3: aaa; break; case 5: bbb; break; default: zzz; break; } ist eigentlich ein if $a == 3 mach aaa, sonst-wenn $a == 5 mach bbb sonst mach zzz. Diese Lösung hier ist tatsächlich eine kompaktere Schreibweise eines if true == ($count <= 20) tun aaa sonst-wenn true == ($count <=40) tun bbb sonst wenn true == ($count <=60) mach ccc sonst mach zzz. Nichts Schlimmes daran, oder?

    – Xavi Montero

    31. Juli 2021 um 15:34 Uhr


  • Das ist eine seltsame Verwendung für switch ()jeweils in den meisten Sprachen case muss ein konstantes Literal sein. Es ist seltsam zu sehen, dass PHP dies unterstützt.

    – Havenar

    2. November 2021 um 20:45 Uhr

Schalter können das nicht, aber in diesem speziellen Fall können Sie so etwas tun:

switch ((int)(($count - 1) / 20)) {
    case 0:
        $priority = 'low';
        break;
    case 1:
        $priority = 'medium';
        break;
    case 2:
        $priority = 'high';
        break;
    case 3:
        $priority = 'severe';
        break;
}

Also rein (int)(($count - 1) / 20) alle Werte von 0 bis 20 ergeben 0, 21 bis 40 ergeben 1 und so weiter, sodass Sie für diesen Zweck die switch-Anweisung verwenden können.

Und da wir Werte verketten, können wir sogar zu einem Array vereinfachen:

$priorities = ['low', 'medium', 'high', 'severe'];
$priority = $priorities[(int)(($count - 1) / 20)];

  • Sie müssen nicht als int umwandeln, da PHP keine Gleitkommaschlüssel zulässt – sie werden automatisch auf ganze Zahlen gekürzt. 3v4l.org/R1kL1

    – mickmackusa

    10. Oktober 2019 um 13:53 Uhr

  • @mickmackusa mmm … auf jeden Fall nehme ich an, dass es ratsam ist, den Code zukunftssicher zu machen und sich nicht auf obskure Konvertierungen zu verlassen.

    – Havenar

    10. Oktober 2019 um 21:20 Uhr

  • Netter Effizienztrick – gefällt mir 🙂

    – John Ruiz

    28. Oktober 2021 um 17:04 Uhr

Benutzer-Avatar
Bytephunk

Es gibt einen Weg, der in PHP 7 mit ternären Zuweisungsoperatoren funktioniert. Der Operator wurde früher eingeführt (5.4?), aber ich habe den Code nie auf anderen Versionen getestet. Ich habe den ganzen Schaltercode geschrieben dort, der Kürze halber ist hier jedoch nur die spezifische Klausel. Angenommen, wir möchten, dass die Bedingung für alle Zahlen größer oder gleich fünf gilt:

switch($value){
    case ($value >= 5 ? $value : !$value): // Do something here
    break;
}

Entweder lassen wir den $value unverändert passieren oder wir negieren den Wert entsprechend der Bedingung. Ein $-Wert wird immer mit sich selbst übereinstimmen oder den Test gegen seine Negation nicht bestehen.

  • Kann bestätigen, dass dieser Ansatz bis mindestens PHP 5.5 funktioniert

    – Ole Haugset

    20. Februar 2018 um 12:11 Uhr

Nein. switch() Anweisungen sind für die Durchführung mehrerer Gleichheitstests. Sie sind im Grunde nur eine etwas einfacher zu lesende (aber auch gefährlichere) Version davon

if (x == 'a') { ... }
else if (x == 'b') { ... } 
else if (x == 'c') { ... }

Code. Es gibt keine Möglichkeit, a zu ändern switch() Weg von == zu < oder irgendein anderer Vergleichsoperator. Es ist ausschließlich für Gleichheitstests.

Benutzer-Avatar
Milchkeks

Verwendung der ternärer Operator:

$priority =
    // "switch" comparison for $count
    $count <= 20 ? 'low' :
    ($count <= 40 ? 'medium' :
    ($count <= 60 ? 'high' :
    // default above 60
    'severe'));

Ich kenne die allgemeine Beschwerde, dass ternäre Operatoren schwer zu verstehen sein können, aber das ist einfach zu einfach mit einem einfachen ?:.

Es funktioniert wie die Excel „Wenn“-Formel:

=IF( logical_test, value_if_true, value_if_false )
$variable = logical_test ? value_if_true : value_if_false

Und Sie können die verschachteln Wenn Aussagen (setzen Sie eine zweite ?: im ‘value_if_false’-Abschnitt des ersten), wo es sicherlich verwirrend werden kann, es zu lesen, aber weniger, wenn Sie es Zeile für Zeile schreiben, wie oben.

Mein obiger Code entspricht im Grunde dem if() Aussage vom OP geschrieben.

  • Oh, ich habe @bytephunk nicht mit ternären Operatoren gesehen, bevor ich gepostet habe

    – Milchkeks

    14. Januar 2020 um 8:21 Uhr

Benutzer-Avatar
Peter Mortensen

Ich kann auch bestätigen, dass die Antwort von bytepunk hier funktioniert.

Erweitern Sie das Konzept auch mit PHP 7:

switch ($interval->days)
{
    case 0:
        return '1 day';
        // break;
    case (($interval->days >= 1 && $interval->days <= 7) ?? $interval->days):
        return '1 week';
        // break;
    case (($interval->days >= 8 && $interval->days <= 31) ?? $interval->days):
        return '1 month';
        // break;
    case (($interval->days >= 31 && $interval->days <= 93) ?? $interval->days):
        return '2-3 months';
        // break;
    default:
        return '3+ months';
}

Ich gebe zu, dass dies nicht der sauberste Code ist, also würde es vielleicht etwas aufräumen, jeden Fall mit einer statisch ähnlichen reinen Funktion zu umhüllen, und nicht zu vergessen, jede Funktion passend zu benennen (oder eine generische Funktion mit Parametern zu erstellen). der Fall. Dadurch wird es besser lesbar.

  • Oh, ich habe @bytephunk nicht mit ternären Operatoren gesehen, bevor ich gepostet habe

    – Milchkeks

    14. Januar 2020 um 8:21 Uhr

1014990cookie-checkVerwendung von Vergleichsoperatoren in einer PHP-‘switch’-Anweisung

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy