Beste Möglichkeit, einen PHP-Switch mit mehreren Werten pro Fall durchzuführen?
Lesezeit: 8 Minuten
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,
@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
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
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 :
+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
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);
}
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
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
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
13460400cookie-checkBeste Möglichkeit, einen PHP-Switch mit mehreren Werten pro Fall durchzuführen?yes
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