Beste Möglichkeit, einen PHP-Switch mit mehreren Werten pro Fall durchzuführen?

Lesezeit: 8 Minuten

Benutzer-Avatar
Jason Davis

Wie würden Sie diese PHP-Switch-Anweisung ausführen?

Beachten Sie auch, dass dies viel kleinere Versionen sind, der 1, die ich erstellen muss, werden viel mehr Werte hinzugefügt.

Version 1:

switch ($p) { 
    case 'home': 
    case '': 
        $current_home="current";
    break; 

    case 'users.online': 
    case 'users.location': 
    case 'users.featured': 
    case 'users.new': 
    case 'users.browse': 
    case 'users.search': 
    case 'users.staff': 
        $current_users="current";
    break;

    case 'forum': 
        $current_forum = 'current';
    break; 
} 

Version 2:

switch ($p) { 
    case 'home': 
        $current_home="current";
    break; 

    case 'users.online' || 'users.location' || 'users.featured' || 'users.browse' || 'users.search' || 'users.staff': 
        $current_users="current";
    break;

    case 'forum': 
        $current_forum = 'current';
    break; 
} 

UPDATE – Testergebnisse

Ich habe einen Geschwindigkeitstest mit 10.000 Iterationen durchgeführt,

Time1: 0.0199389457703 // If-Anweisungen
Time2: 0.0389049446106 // Anweisungen wechseln
Zeit3: 0.106977939606 // Arrays

  • Version 2 tut nicht das, was Sie denken.

    – zu viel php

    21. August 2009 um 2:20 Uhr

  • Version 2 funktioniert nicht, lesen Sie hier für weitere Informationen: nutt.net/2004/12/28/multiple-cases-for-switch-construct

    – GusDeCool

    11. Mai 2012 um 21:55 Uhr

  • @jasondavis Wenn Sie variable Variablen verwenden, haben Sie einen Code, der KLEIN UND EINFACH ist, genau so, wie ich ihn mag =) Sehen Sie sich meine Antwort an, sie ist getestet und funktioniert.

    – Omar

    16. November 2012 um 20:34 Uhr


Für jede Situation, in der Sie eine unbekannte Zeichenfolge haben und herausfinden müssen, welche von vielen Sonstiges Strings, mit denen es übereinstimmt, ist die einzige Lösung, die nicht langsamer wird, wenn Sie mehr Elemente hinzufügen, ein Array zu verwenden, aber alle möglichen Strings als Schlüssel zu haben. Ihr Schalter kann also durch Folgendes ersetzt werden:

// used for $current_home="current";
$group1 = array(
        'home'  => True,
        );

// used for $current_users="current";
$group2 = array(
        'users.online'      => True,
        'users.location'    => True,
        'users.featured'    => True,
        'users.new'         => True,
        'users.browse'      => True,
        'users.search'      => True,
        'users.staff'       => True,
        );

// used for $current_forum = 'current';
$group3 = array(
        'forum'     => True,
        );

if(isset($group1[$p]))
    $current_home="current";
else if(isset($group2[$p]))
    $current_users="current";
else if(isset($group3[$p]))
    $current_forum = 'current';
else
    user_error("\$p is invalid", E_USER_ERROR);

Das sieht nicht so sauber aus wie ein switch()aber es ist das einzige schnell Lösung, die nicht das Schreiben einer kleinen Bibliothek von Funktionen und Klassen beinhaltet, um sie sauber zu halten. Es ist immer noch sehr einfach, Elemente zu den Arrays hinzuzufügen.

  • Um technisch korrekt zu sein, wird dies langsamer, wenn Sie mehr Elemente hinzufügen, es wird nur langsamer, viel langsamer – Hash-Tabellen sind blitzschnell, aber sie sind nicht magisch 🙂

    – Stimmungsboom

    27. Februar 2013 um 19:49 Uhr

Benutzer-Avatar
zu viel php

Version 2 funktioniert nicht!!

case 'users.online' || 'users.location' || ...

ist genau das gleiche wie:

case True:

und das case wird für jeden Wert von ausgewählt $pwenn nicht $p ist die leere Zeichenfolge.

|| Hat innerhalb von a keine besondere Bedeutung case Aussage, du vergleichst nicht $p zu jeder dieser Zeichenfolgen überprüfen Sie nur, ob dies nicht der Fall ist False.

  • ok, würden Sie denken, dass die Verwendung eines Schalters oder einer if-Anweisung schneller ist, als mehrere Arrays zu erstellen und mehrmals zu prüfen, ob sich ein Wert in einem Array befindet?

    – Jason Davis

    21. August 2009 um 2:28 Uhr

  • Ich habe noch nie etwas gehört oder gelesen, das mich glauben lässt, dass ein switch() schneller wäre. Eine Route wird immer noch einen ganzen Haufen String-Vergleiche machen.

    – zu viel php

    21. August 2009 um 2:35 Uhr

  • Hier ist etwas, das zeigt, dass ein Array möglicherweise langsamer ist stackoverflow.com/questions/324665/…

    – Jason Davis

    21. August 2009 um 2:54 Uhr

Benutzer-Avatar
karim79

Setzen Sie diese vielen Werte in ein Array und fragen Sie das Array ab, da der Schalterfall die zugrunde liegende Semantik dessen zu verbergen scheint, was Sie erreichen möchten, wenn eine Zeichenfolgenvariable als Bedingung verwendet wird, was das Lesen und Verstehen erschwert, z :

$current_home = null;
$current_users = null;
$current_forum = null;

$lotsOfStrings = array('users.online', 'users.location', 'users.featured', 'users.new');

if(empty($p)) {
    $current_home="current";
}

if(in_array($p,$lotsOfStrings)) {
    $current_users="current";
}

if(0 === strcmp('forum',$p)) {
    $current_forum = 'current';
}

  • +1 Als ich die Frage zum ersten Mal las, fiel mir zuerst diese Lösung ein. Wenn die Anzahl der Fälle zunimmt, müssen Sie dem Array nur noch Werte hinzufügen und sich darauf verlassen, dass in_array seine Arbeit erledigt.

    – Randel

    21. August 2009 um 2:18 Uhr

  • In meinem Fall hätte ich auf diese Weise viele verschiedene Arrays, also würde ich das in_array gegen mehrere Arrays ausführen. Glauben Sie, dass es einen Leistungsgewinn auf eine Weise gegenüber einer anderen gibt?

    – Jason Davis

    21. August 2009 um 2:30 Uhr

  • Ich habe nicht versucht, Benchmarking durchzuführen, es ist einfacher zu lesen, insbesondere wenn Sie Konstanten verwenden. Wie viele verschiedene Arrays (und Größen) erwarten Sie zu verwenden?

    – Randel

    21. August 2009 um 2:34 Uhr

  • Ich denke nicht, dass es einen spürbaren Leistungsunterschied geben wird. Selbst wenn es so wäre, würde ich wahrscheinlich immer noch bei dem oben genannten bleiben, weil es für mich in Bezug auf Lesbarkeit und Wartbarkeit einfach sinnvoller ist.

    – karim79

    21. August 2009 um 2:38 Uhr

  • @Randell dies wird für eine Menüauswahl auf einer Website mit hohem Verkehr verwendet, sodass es nur etwa 8 Arrays gibt und einige von ihnen jeweils bis zu etwa 15 Elemente enthalten können. Ich weiß, dass es nicht GROSS ist, aber es wird zusätzliche Arbeit geleistet und es gibt wird viel Verkehr sein und das wäre etwas, das bei jedem einzelnen Seitenladevorgang durchgeführt wird. Deshalb frage ich

    – Jason Davis

    21. August 2009 um 2:42 Uhr

Benutzer-Avatar
Peter

Der Vollständigkeit halber weise ich darauf hin, dass die kaputte “Version 2”-Logik durch eine funktionierende switch-Anweisung ersetzt werden kann, und Auch Verwenden Sie Arrays für Geschwindigkeit und Klarheit, wie folgt:

// used for $current_home="current";
$home_group = array(
    'home'  => True,
);

// used for $current_users="current";
$user_group = array(
    'users.online'      => True,
    'users.location'    => True,
    'users.featured'    => True,
    'users.new'         => True,
    'users.browse'      => True,
    'users.search'      => True,
    'users.staff'       => True,
);

// used for $current_forum = 'current';
$forum_group = array(
    'forum'     => True,
);

switch (true) {
    case isset($home_group[$p]):
        $current_home="current";
        break;
    case isset($user_group[$p]):
        $current_users="current";
        break;
    case isset($forum_group[$p]):
        $current_forum = 'current';
        break;
    default:
        user_error("\$p is invalid", E_USER_ERROR);
}    

Benutzer-Avatar
lilHar

Heutzutage kann man…

switch ([$group1, $group2]){
    case ["users", "location"]:
    case ["users", "online"]:
        Ju_le_do_the_thing();
        break;
    case ["forum", $group2]:
        Foo_the_bar();
        break;
}

Hier ist ein fertiger Codesatz, der das Konzept demonstriert:

<?php

function show_off_array_switch(){
  $first_array = ["users", "forum", "StubbornSoda"];
  $second_array = ["location", "online", "DownWithPepsiAndCoke"];

  $rand1 = array_rand($first_array);
  $rand2 = array_rand($second_array);

  $group1 = $first_array[$rand1];
  $group2 = $second_array[$rand2];

  switch ([$group1, $group2]){
      case ["users", "location"]:
      case ["users", "online"]:
          echo "Users and Online";
          break;
      case ["forum", $group2]:
          echo "Forum and variable";
          break;
      default:
          echo "default";
  }
  echo "\nThe above result was generated using the array: \n" . print_r([$group1, $group2], true);
}

for ($i = 0; $i < 10; $i++){
  show_off_array_switch();
}

Folgendes hat (für einen zufälligen Lauf) Folgendes ausgegeben:

 Users and Online
The above result was generated using the array: 
Array
(
    [0] => users
    [1] => online
)
Users and Online
The above result was generated using the array: 
Array
(
    [0] => users
    [1] => online
)
default
The above result was generated using the array: 
Array
(
    [0] => users
    [1] => DownWithPepsiAndCoke
)
Users and Online
The above result was generated using the array: 
Array
(
    [0] => users
    [1] => location
)
Forum and variable
The above result was generated using the array: 
Array
(
    [0] => forum
    [1] => DownWithPepsiAndCoke
)
Forum and variable
The above result was generated using the array: 
Array
(
    [0] => forum
    [1] => DownWithPepsiAndCoke
)
Forum and variable
The above result was generated using the array: 
Array
(
    [0] => forum
    [1] => online
)
default
The above result was generated using the array: 
Array
(
    [0] => StubbornSoda
    [1] => location
)
Users and Online
The above result was generated using the array: 
Array
(
    [0] => users
    [1] => location
)
Users and Online
The above result was generated using the array: 
Array
(
    [0] => users
    [1] => location
)

  • hat das jemand getestet?

    – Tanzeel

    14. Mai 2021 um 14:53 Uhr

  • Ich habe, und nur um sicherzugehen, habe ich es gerade noch einmal überprüft. Funktioniert immer noch gut!

    – lilHar

    14. Mai 2021 um 16:06 Uhr


  • @Tanzeel Für dich, habe gerade ein vollständig lauffähiges Codebeispiel hinzugefügt, um zu zeigen, dass es funktioniert.

    – lilHar

    14. Mai 2021 um 16:14 Uhr

Benutzer-Avatar
Mark Ruschakoff

Wenn jeder Wenn Sie Ihren Code sonst nie pflegen müssten, würden sie Version 2 mit ziemlicher Sicherheit doppelt angehen – das ist extrem nicht standardisiert.

Ich würde bei Version 1 bleiben. Ich bin jedoch der Meinung, dass Fallaussagen ohne eigenen Anweisungsblock explizit sein sollten // fall through kommentieren Sie daneben, um anzuzeigen, dass es tatsächlich Ihre Absicht ist, durchzufallen, wodurch jegliche Unklarheit beseitigt wird, ob Sie die Fälle anders handhaben und vergessen oder so etwas.

  • hat das jemand getestet?

    – Tanzeel

    14. Mai 2021 um 14:53 Uhr

  • Ich habe, und nur um sicherzugehen, habe ich es gerade noch einmal überprüft. Funktioniert immer noch gut!

    – lilHar

    14. Mai 2021 um 16:06 Uhr


  • @Tanzeel Für dich, habe gerade ein vollständig lauffähiges Codebeispiel hinzugefügt, um zu zeigen, dass es funktioniert.

    – lilHar

    14. Mai 2021 um 16:14 Uhr

Benutzer-Avatar
pguardiario

Einige andere Ideen, die noch nicht erwähnt wurden:

switch(true){ 
  case in_array($p, array('home', '')): 
    $current_home="current"; break;

  case preg_match('/^users\.(online|location|featured|new|browse|search|staff)$/', $p):
    $current_users="current"; break;

  case 'forum' == $p:
    $current_forum = 'current'; break; 
}

Jemand wird sich wahrscheinlich über Lesbarkeitsprobleme mit #2 beschweren, aber ich hätte kein Problem damit, solchen Code zu erben.

  • Lustig, ein Kumpel von mir hat mir gerade einen sehr ähnlichen Code geschickt, der sagt, dass er funktioniert, und ich bin sofort zu Stack Overflow gekommen, um zu sehen, ob jemand anderes an dies als Lösung gedacht hat. Ich finde es ziemlich cool

    – samrap

    8. November 2016 um 22:03 Uhr

  • Saubere Umsetzung.

    – Hayatu Mohammed Abubakar

    7. April 2019 um 14:15 Uhr

1346040cookie-checkBeste Möglichkeit, einen PHP-Switch mit mehreren Werten pro Fall durchzuführen?

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

Privacy policy