[PHP] Speciale 'Delphi-stijl' switch

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Spinal
  • Registratie: Februari 2001
  • Laatst online: 19-09 13:37
In Delphi kon je het volgende doen met een case:
code:
1
2
3
4
5
case i of
  0..5: x:=1;
  6..10: x:=2;
  11..15: x:=3;
end;


Voor de mensen die niet bekend zijn met Delphi, dit houdt ongeveer het volgende in:
code:
1
2
3
4
5
6
if (i>=0 && i<=5)
  x==1;
elseif (i>=6 && i<=10)
  x==2;
elseif (i>=11 && i<=15)
  x==3;

Maar ik vind persoonlijk een switch/case variant overzichtelijker staan. Is dit mogelijk zoals in Delphi? Ik kon het niet vinden op http://nl2.php.net/switch en zoeken bij Google op 'php delphi style case' levert ook niks nuttigs op...
Alvast bedankt!

Full-stack webdeveloper in Groningen


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Nu online

Creepy

Tactical Espionage Splatterer

Ja en nee.

Nee, een .. o.i.d. kent php niet. Je kan echter prima cases "stacken".

code:
1
2
3
4
5
6
7
8
9
switch ($i) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5: { /* code hier voor 0..5*/ break; }
case 6: {}
}

De break dient ervoor om te stoppen met uitvoeren na case 5. Anders wordt automatisch ook nog case 6 uitgevoerd.

[ Voor 3% gewijzigd door Creepy op 12-10-2004 22:45 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • Spinal
  • Registratie: Februari 2001
  • Laatst online: 19-09 13:37
Ik had idd gezien dat dat kon, maar dan vind ik misschien de if/elseif variant nog wel mooier staan dan dat :/ Jammer dat er niet iets kan van
code:
1
2
3
4
switch ($i) {
  case (0<5) { ... }
  case (6<10) { ... }
}

ofzo, dat zou de code wat netter houden :) Toch bedankt voor de moeite

Full-stack webdeveloper in Groningen


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

ZanderZ schreef op 12 oktober 2004 @ 22:50:
Ik had idd gezien dat dat kon, maar dan vind ik misschien de if/elseif variant nog wel mooier staan dan dat :/ Jammer dat er niet iets kan van
code:
1
2
3
4
switch ($i) {
  case (0<5) { ... }
  case (6<10) { ... }
}

ofzo, dat zou de code wat netter houden :) Toch bedankt voor de moeite
Dat zou sowieso vertalen naar dit:
code:
1
2
3
4
switch ($i) {
  case (true) { ... }
  case (true) { ... }
}

Lijkt me niet echt de bedoeling. ;)

Verder is het in zo'n geval misschien handiger om toch een if/elseif/else block te gebruiken, natuurlijk afhankelijk van hoeveel condities je nodig hebt.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

Verwijderd

Als je ranges gelijkmatig zijn kan je het doen met een geheeltallige deling. Nu zijn je ranges in het voorbeeld niet gelijk, daarom voor "0" de uitzondering:

code:
1
2
3
4
5
6
if (0 == i)
{
    x = 1;
} else {
    x = ( (i-1) \ 5 ) + 1;
};

[ Voor 8% gewijzigd door Verwijderd op 12-10-2004 22:56 ]


Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Als je de voorkeur hebt voor een switch vanwege de leesbaarheid van de code (dat is tenminste vaak waar de switch voor gebruikt wordt, merk ik) is het misschien interessant te kijken naar de alternative syntax voor control structures waar je in PHP de beschikking over hebt.

Anders is het idee van bloog ook zo gek nog niet, alleen dan even wat "praktischer" weergegeven (aangenomen dat $i > 0)
PHP:
1
2
3
4
5
6
7
8
9
10
11
<?
switch ( floor($i / 5) ) {
   case 0: 
      // $i ligt tussen 0 en 4
      break;
   case 1: 
   case 2:
      // $i  ligt tussen 5 en 14
   //etcetera
}
?> 
wees creatief ;)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

Verwijderd

zou dacht echt niet kunnen? ik zou iig het volgende proberen

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
$X == 5;

switch ( true ) { // dus als een statement true is : )

  case ( $X > 0 &&  $X < 6 ): //tussen de 1 en 6
             uitvoeren;
             break;
  case ( $X > 5 &&  $X < 11 ): //tussen de 6 en 10
             uitvoeren;
             break;
  default:
              return false; // ofzo :P
}


lijkt me dat het zo prima kan

Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 16:36
Verwijderd schreef op 12 oktober 2004 @ 23:15:
zou dacht echt niet kunnen? ik zou iig het volgende proberen

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
$X == 5;

switch ( true ) { // dus als een statement true is : )

  case ( $X > 0 &&  $X < 6 ): //tussen de 1 en 6
             uitvoeren;
             break;
  case ( $X > 5 &&  $X < 11 ): //tussen de 6 en 10
             uitvoeren;
             break;
  default:
              return false; // ofzo :P
}


lijkt me dat het zo prima kan
Waarom zou je switchen op TRUE? Als iets TRUE is valt er toch niets meer te switchen...
Je switch dus op een variabele, in jouw geval $X. Dat je dan de condities probeert kan ik volgen. Zij het niet dat:
The case expression may be any expression that evaluates to a simple type, that is, integer or floating-point numbers and strings. Arrays or objects cannot be used here unless they are dereferenced to a simple type.
bron: PHP manual
Condities zijn dus niet toegestaan als cases...

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

T-MOB schreef op 13 oktober 2004 @ 01:39:
Waarom zou je switchen op TRUE? Als iets TRUE is valt er toch niets meer te switchen...
Je switch dus op een variabele, in jouw geval $X. Dat je dan de condities probeert kan ik volgen. Zij het niet dat:
[...]
bron: PHP manual
Condities zijn dus niet toegestaan als cases...
Je switcht niet op true, intern doet een switch ook niet meer dan de expressie naast de switch vergelijken met de expressie bij de case. Hier vergelijkt ie dus gewoon true met een expressie, en dat evalueert dan weer naar true of false, waardoor de case werkt. :P

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Abdul Rahman:
zou dacht echt niet kunnen? ik zou iig het volgende proberen

code:
1
snip


lijkt me dat het zo prima kan
Dat lijkt mij eigenlijk ook :P Best wel ingenieus...

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
drm schreef op 13 oktober 2004 @ 02:33:
[...]
Dat lijkt mij eigenlijk ook :P Best wel ingenieus...
Dat lijkt me gewoon zinloos eigenlijk. Het is niet echt leesbaarder dan een paar if/elsif's, en je verliest het voordeel van eenmalige evaluatie, die de switch normaal heeft t.o.v. if/elseif. Dus ik snap niet waarom je dan een case statement van die vorm neer zou zetten.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

Verwijderd

Typisch een vorm van zwaar overtrokken programmeerpurisme ;)

Acties:
  • 0 Henk 'm!

Verwijderd

Grijze Vos schreef op 13 oktober 2004 @ 08:27:
[...]

Dat lijkt me gewoon zinloos eigenlijk. Het is niet echt leesbaarder dan een paar if/elsif's, en je verliest het voordeel van eenmalige evaluatie, die de switch normaal heeft t.o.v. if/elseif. Dus ik snap niet waarom je dan een case statement van die vorm neer zou zetten.
ach, wat is zinloos, zinloos is als je code niet zou werken : ) of het niet zou worden gebruikt.

als de ts het wilt, why not? ik zou het niet gebruiken, maar ik het zo mijn eigen styl en jij ook je eigen.

en ik vind het wel weer overzichtelijker, maar ik heb liever if/else voor de controle

Acties:
  • 0 Henk 'm!

Verwijderd

Verwijderd schreef op 12 oktober 2004 @ 23:15:
zou dacht echt niet kunnen? ik zou iig het volgende proberen

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
$X == 5;

switch ( true ) { // dus als een statement true is : )

  case ( $X > 0 &&  $X < 6 ): //tussen de 1 en 6
             uitvoeren;
             break;
  case ( $X > 5 &&  $X < 11 ): //tussen de 6 en 10
             uitvoeren;
             break;
  default:
              return false; // ofzo :P
}


lijkt me dat het zo prima kan
Vergelijk:
code:
1
2
3
4
5
6
7
8
9
   if ( $X > 0 &&  $X < 6 ) { //tussen de 1 en 6
             uitvoeren;
   }
   else
      if ( $X > 5 &&  $X < 11 ) { //tussen de 6 en 10
                uitvoeren;
      }
      else
                return false; // ofzo :P

:P

Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Grijze Vos:
Dat lijkt me gewoon zinloos eigenlijk. Het is niet echt leesbaarder dan een paar if/elsif's, en je verliest het voordeel van eenmalige evaluatie, die de switch normaal heeft t.o.v. if/elseif. Dus ik snap niet waarom je dan een case statement van die vorm neer zou zetten.
Ach, that's besides the point; ik vind het gewoon leuk gevonden.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Dit soort dingen zijn hardcoded sowieso lelijk, zeker als je veel verschillende waardes hebt. Je kunt ook gewoon alles in een array stoppen en daar een search op doen. Stop er een pointer naar een functie in en je code blijft kort en netjes

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

Verwijderd

.oisyn schreef op 13 oktober 2004 @ 10:20:
Dit soort dingen zijn hardcoded sowieso lelijk, zeker als je veel verschillende waardes hebt. Je kunt ook gewoon alles in een array stoppen en daar een search op doen. Stop er een pointer naar een functie in en je code blijft kort en netjes
maar das de vraag niet : ) zou ik ook doen hoor. Je kunt altijd veel netter en beter proggen, maar voor veel mensen is het gewoon net te abstract : )

[ Voor 12% gewijzigd door Verwijderd op 13-10-2004 13:33 ]


Acties:
  • 0 Henk 'm!

  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
ZanderZ schreef op 12 oktober 2004 @ 22:41:
In Delphi kon je het volgende doen met een case:
[...]
Persoonlijk is dit netter te vangen in een expressie x = -1 * i /5, maar ik kan me ingewikkeldere voorbeelden voorstellen. Echter dan ga je toch al denken aan magic numbers (bijv alleen in het geval van exitcode 32 en 23).

Voor de leesbaarheid kun je dan beter http://www.refactoring.co...WithSymbolicConstant.html gebruiken. Of helemaal geen switch liever http://www.refactoring.co...onalWithPolymorphism.html

Acties:
  • 0 Henk 'm!

  • Sosabowski
  • Registratie: Juni 2003
  • Laatst online: 18-09 21:03

Sosabowski

nerd

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
<?
switch ( ($i-($i%5))/5 ) {
   case 0:
      // $i ligt tussen 0 en 4
      break;
   case 1:
      // $i ligt tussen 5 en 9
      break;
   case 2:
      // $i  ligt tussen 9 en 14
   //etcetera
}
?>

Zo heb ik m wel eens gebruikt. Komt eigelijk neer op wat drm al zei.

The whole problem with the world is that fools and fanatics are always so certain of themselves, and wiser people so full of doubts. -- Bertrand Russell


Acties:
  • 0 Henk 'm!

  • Spinal
  • Registratie: Februari 2001
  • Laatst online: 19-09 13:37
Bedankt voor alle antwoorden :)
De waarden zijn helaas niet gelijkmatig verdeelt, anders was de oplossing van bloog inderdaad mooi geweest.
.oisyn, ik ben nog niet zolang bezig met PHP, dus ik weet nog niet hoe je met pointers werkt, daar moet ik me misschien eens in gaan verdiepen... Nog tips waar ik nuttige informatie kan vinden?

Full-stack webdeveloper in Groningen


Acties:
  • 0 Henk 'm!

  • mocean
  • Registratie: November 2000
  • Laatst online: 04-09 10:34
of je doet zoiets, een array dieaangeeft welke case bij een waarde hoort.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
array[0]=1;
array[1]=1;
array[2]=2;
array[3]=2;
array[4]=2;
array[5]=2;
array[6]=3;
array[7]=3;
array[8]=3;
array[9]=3;
array[10]=3;
array[11]=4;

switch (array[$var]){
   case 1:
                 //code
   break;
   case 2:
                 //code 
   break;
   case 3:
                  //code
   break;
   case 4:
                  //code
   break;
}

Koop of verkoop je webshop: ecquisition.com


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Verwijderd schreef op 13 oktober 2004 @ 09:43:
[...]


ach, wat is zinloos, zinloos is als je code niet zou werken : ) of het niet zou worden gebruikt.
PHP:
1
2
3
4
5
6
7
8
9
if(true) {
  if(true) {
    if(true) {
      if(true) {
        echo "zinnig";
      }
    }
  }
}


Het wordt gebruikt en het werkt, dus is het zinnig? Nee hoor. :)

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

Verwijderd

Grijze Vos schreef op 13 oktober 2004 @ 17:21:
[...]

PHP:
1
2
3
4
5
6
7
8
9
if(true) {
  if(true) {
    if(true) {
      if(true) {
        echo "zinnig";
      }
    }
  }
}


Het wordt gebruikt en het werkt, dus is het zinnig? Nee hoor. :)
als jij het voor je code nodig hebt : ) why not?

maja, je hebt het over 4 true statements : ) dus je kunt ze net zo goed weghalen...
mijn voorbeeld kon je niet de switch weghalen, maar moest je het met een andere voorbeeld oplossen. heel ander verhaal

Acties:
  • 0 Henk 'm!

  • Spinal
  • Registratie: Februari 2001
  • Laatst online: 19-09 13:37
mocean schreef op 13 oktober 2004 @ 15:40:
of je doet zoiets, een array dieaangeeft welke case bij een waarde hoort.
[...]
Is in mijn geval niet handig, aangezien het om waarden gaat tussen 0 en 4 miljard ;)
Ik denk dat het toch maar gewoon bij een if/elseif houd, bedankt voor alle reacties!

Full-stack webdeveloper in Groningen


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Verwijderd schreef op 13 oktober 2004 @ 19:34:
[...]


als jij het voor je code nodig hebt : ) why not?

maja, je hebt het over 4 true statements : ) dus je kunt ze net zo goed weghalen...
mijn voorbeeld kon je niet de switch weghalen, maar moest je het met een andere voorbeeld oplossen. heel ander verhaal
Ik heb iets aan te merken op je definitie van zinloos, en daarbij gebruik ik mijn voorbeeld. Overigens, om precies te zijn moet je mijn vierdubbele if(true) met een echo ook vervangen voor een ander stuk code (alleen de echo), dus in wezen blijft de situatie hetzelfde.

Ik vind jouw switch gewoon onleesbaarder en minder onderhoudbaar dan if/elseif's. Daarbij komt nog eens dat je alle voordelen die een switch normaal heeft al teniet heb gedaan, en noem ik het dus zinloos.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

ZanderZ:
Is in mijn geval niet handig, aangezien het om waarden gaat tussen 0 en 4 miljard ;)
Ik denk dat het toch maar gewoon bij een if/elseif houd, bedankt voor alle reacties!
Euhm... betekent dat dat je ca 900 miljoen else if's nodig gaat hebben :? :?

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

Verwijderd

En om het geheel nog eens nodeloos gecompliceerd te maken:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
function range1() {
  /* ... */
}

function range2() {
  /* ... */
}

function range3() {
  /* ... */
}

function default() {
  /* ... */
}

$cases = Array(
  Array(
    "lowinc" => 0, 
    "highex" => 1000,
    "call" => "range1"
  ),
  Array(
    "lowinc" => 1000,
    "highex" => 400000,
    "call" => "range2"
  ),
  Array(
    "lowinc" => 800000,
    "highex" => 800100,
    "call" => "range3"
  )
);

$switchvalue = /* ... */;

$casechosen = "default";
foreach ($cases as $case) {
  if ($case["lowinc"] <= $switchvalue && $switchvalue < $case["highex"])
    $casechosen = $case["call"];  
}

$casechosen();


;)

Over het algemeen vind ik data-driven programma's mooier dan hardcoded programma's. Ze zijn vaak makkelijker uit te breiden.

[ Voor 35% gewijzigd door Verwijderd op 14-10-2004 15:06 ]


Acties:
  • 0 Henk 'm!

  • Spinal
  • Registratie: Februari 2001
  • Laatst online: 19-09 13:37
drm: nee, dat valt mee :) Het zullen er zeker niet meer dan 10 worden.
OneOfBorg: tja... zou ook nog kunnen... Maar ik hoef geen functie aan te roepen, alleen een variabele definiëren. Dan is dit denk ik niet geschikt.

Full-stack webdeveloper in Groningen


Acties:
  • 0 Henk 'm!

Verwijderd

ZanderZ schreef op 15 oktober 2004 @ 14:14:
drm: nee, dat valt mee :) Het zullen er zeker niet meer dan 10 worden.
OneOfBorg: tja... zou ook nog kunnen... Maar ik hoef geen functie aan te roepen, alleen een variabele definiëren. Dan is dit denk ik niet geschikt.
Net wel; dan wordt het nog veel makkelijker. Dat wil zeggen, als het altijd dezelfde variabele is die afhankelijk van de cases een andere waarde moet krijgen.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$cases = Array( 
  Array( 
    "lowinc" => 0, 
    "highex" => 1000, 
    "value" => "val1" 
  ), 
  Array( 
    "lowinc" => 1000, 
    "highex" => 400000, 
    "value" => "val2" 
  ), 
  Array( 
    "lowinc" => 800000, 
    "highex" => 800100, 
    "value" => "val3" 
  ) 
); 

$switchvalue = /* ... */; 

$returnvalue = "default"; 
foreach ($cases as $case) { 
  if ($case["lowinc"] <= $switchvalue && $switchvalue < $case["highex"]) 
    $returnvalue = $case["value"];
} 
// Klaar

echo $returnvalue;

Acties:
  • 0 Henk 'm!

  • Spinal
  • Registratie: Februari 2001
  • Laatst online: 19-09 13:37
Ziet er goed uit zo :) Als ik die cases-array in mijn config bestand zet ziet het er iig een stuk netter uit! Bedankt, ik ga er binnenkort mee bezig en ik zal jouw naam zeker eervol vermelden :)

Full-stack webdeveloper in Groningen

Pagina: 1