Robert: haupts. PHP: switch-case mit ungewöhnl. Verwendung von break

Hallöle,

switch case dürfte ja jedem Programmierer ein Begriff sein.

Sieht ja üblicherweise etwa so aus:

  
switch($irgendeinevariable)  
{  
case 1:  
   //irgendwas  
   break;  
case 2:  
   //irgendwas  
   break;  
case 3:  
   //irgendwas  
   break;  
default:  
   //irgendwas  
   break;  
}  

Jetzt hab ich in einem der case-Zweige aber eine Konstruktion

  
case 1:  
   if (irgendeineBedingung)  
   {  
       //tu irgendwas  
   }  
   else  
   {  
      //irgendwas  
      if (irgendeineBedingung)  
      {  
          //tu irgendwas  
      }  
      else  
      {  
         //irgendwas  
         if (irgendeineBedingung)  
         {  
             //tu irgendwas  
         }  
         else  
         {  
            //irgendwas  
            if (irgendeineBedingung)  
            {  
                //tu irgendwas  
            }  
            else  
            {  
               //irgendwas  
            }  
         }  
      }  
   }  
   break;  

mit einer ziemlichen Schachtelung (wesentlich mehr Ebenen als hier angedeutet).
Im if-Fall also jeweils ein, zwei Zeilen (Fehlermeldung setzen) und dann einige Aktionen im Else-Zweig.

Gibt ne ziemlich unschöne Schachtelung - und nach dem jeweiligen else passiert nichts mehr.
Das ganze ließe sich also auch per

  
case 1:  
   if (irgendeineBedingung)  
   {  
       //tu irgendwas  
       break;  
   }  
   //irgendwas  
   if (irgendeineBedingung)  
   {  
       //tu irgendwas  
       break;  
   }  
   //irgendwas  
   if (irgendeineBedingung)  
   {  
       //tu irgendwas  
       break;  
   }  
   //irgendwas  
   if (irgendeineBedingung)  
   {  
       //tu irgendwas  
       break;  
   }  
   //irgendwas  
   break;  

umformen, also statt des else-Zweigs im if ein break und den ehemaligen else-Zweig nicht mehr verschachtelt - wesentlich weniger Einrückung (elseif geht nicht, da zwischen dem else und dem nächsten if erst noch was anderes steht)

Mit meinem PHP hier funktioniert das auch wie gewünscht.

Jetzt meine Frage:
Ist das ein echtes Feature von PHP oder nur eine Lücke, die vielleicht in der nächsten PHP-Version geschlossen wird?

Und wie sieht das in anderen Programmiersprachen aus mit dem break, das tief verschachtelt in if-else-Konstruktionen steht?

cu,
Robert

  1. Jetzt meine Frage:
    Ist das ein echtes Feature von PHP oder nur eine Lücke, die vielleicht in der nächsten PHP-Version geschlossen wird?

    Das ist ein gewünschtes und definiertes Verhalten.

    Und wie sieht das in anderen Programmiersprachen aus mit dem break, das tief verschachtelt in if-else-Konstruktionen steht?

    C, C++ und Java verhalten sich genau so.

    1. Hallöle,

      Ist das ein echtes Feature von PHP oder nur eine Lücke, die vielleicht in der nächsten PHP-Version geschlossen wird?
      Das ist ein gewünschtes und definiertes Verhalten.

      Hab ich mir schon fast gedacht, aber im Manual hab ich nur das hier gefunden:

      PHP continues to execute the statements until the end of the switch block, or the first time it sees a break statement.

      Das hieße aber genaugenommen, daß z.B. bei

        
      switch($irgendwas)  
      {  
      case 1:  
         while ($sonstwas)  
         {  
            if ($wasanderes)  
               break;  
         }  
         echo "hallo";  
         break;  
      case 2:  
         break;  
      }  
      
      

      das "hallo" nicht ausgegeben werden dürfte, wenn die Bedingung $wasanderes true ist - denn dann trifft der Interpreter auf ein break und müßte laut Beschreibung die Abarbeitung abbrechen.

      Aber wenn das Verhalten so definiert ist wie es tatsächlich von meinem PHP-Interpreter gemacht wird, dann kann ich das also beruhigt in meinen Scripts benutzen, ohne befürchten zu müssen, daß beim PHP-Update mir das Script um die Ohren fliegt ...

      cu,
      Robert

      1. PHP continues to execute the statements until the end of the switch block, or the first time it sees a break statement.

        Du hast das missinterpretiert. Sees heißt hier nicht, dass er das erste Vorkommen zählt, sondern das erste break, auf das er bei der Ausführung trifft. Ist die Bedingung nicht erfüllt, trifft er Interpreter nicht auf das break.

        1. Hallöle,

          PHP continues to execute the statements until the end of the switch block, or the first time it sees a break statement.

          Du hast das missinterpretiert. Sees heißt hier nicht, dass er das erste Vorkommen zählt, sondern das erste break, auf das er bei der Ausführung trifft. Ist die Bedingung nicht erfüllt, trifft er Interpreter nicht auf das break.

          Ich hatte ja geschrieben, "wenn die Bedingung zutrifft".

          Tatsächlich bricht das break im if in der while-Schleife im case aber nicht den case ab, sondern lediglich die while-Schleife.

          Es müßte also eigentlich heißen (Ergänzung mit ### markiert):

          PHP continues to execute the statements until the end of the switch block, or the first time it sees a break statement ### which is not inside a while, for, foreach, do or nested switch statement ###.

          cu,
          Robert

          1. Hallo Robert

            Tatsächlich bricht das break im if in der while-Schleife im case aber nicht den case ab, sondern lediglich die while-Schleife.

            Es müßte also eigentlich heißen (Ergänzung mit ### markiert):

            PHP continues to execute the statements until the end of the switch block, or the first time it sees a break statement ### which is not inside a while, for, foreach, do or nested switch statement ###.

            Lies lieber bei break nach, dort steht es korrekt. Beachte bitte das optionale numerische Argument.

            Freundliche Grüße

            Vinzenz

      2. PHP continues to execute the statements until the end of the switch block, or the first time it sees a break statement.

        Das hieße aber genaugenommen, daß z.B. bei

        switch($irgendwas)
        {
        case 1:
           while ($sonstwas)
           {
              if ($wasanderes)
                 break;
           }
           echo "hallo";
           break;
        case 2:
           break;
        }

        
        >   
        > das "hallo" nicht ausgegeben werden dürfte, wenn die Bedingung $wasanderes true ist - denn dann trifft der Interpreter auf ein break und müßte laut Beschreibung die Abarbeitung abbrechen.  
        >   
          
        dein 'statement' ist der switch-block.  
        breaks sind aber auch für andere blöcke wie z.b. schleifen vorgesehen.  
        die blöcke werden zur laufzeit nacheinander geöffnet (stack). das auftreten eines breaks reduziert diesen stack, so dass der vorhergehende block aktiv ist.  
          
        deshalb wird 'hallo' ausgegeben.