*Markus: Umgang mit String und int

Hallo,

ich habe folgende Schleife:

  
            for ($i = 0; $i < count($resultlist); $i++)  {  
                $zeile = $resultlist[$i]+1;  
                 echo 'Zeile ' . $zeile . ': ' . $filecontent[$resultlist[$i]] . '<br />';  
            }  

Hätte ich statt $zeile $resultlist[$i]+1 eingefügt, wäre die Ausgabe pro Zeile immer 1 gewesen. Die richtige Ausgabe wäre $resultlist[$i] plus 1. $resultlist enthält eine Liste von Zeilennummern. Da die Numemrn aber bei 0 anfangen, muss ich zur Ausgabe 1 addieren.
Ich versuchte Lösungen wie ((int)$resultlist[$i])++, half aber nichts. Seltsamerweise lieferte ++$resultlist[$i] zwar die richtige Zeilennummer, d.h. hier wurde plötzlich ein int erkannt, jedoch bedeutet das natürlich, dass die Variable postinkrementiert wird, was ich in diesem Fall aber nicht will.

Wie geht PHP hier vor? Wieso wird einmal ein int, dann wieder ein String erkannt, und wie könnte ich es ohne eine Zusatzvariable lösen? (das o.g. beispiel liefert das richtige Ergebnis, aber eben nur mithilfe der Zusatzvariable $zeile).

Danke für die Antworten,
Markus

  1. Hallo,

    for ($i = 0; $i < count($resultlist); $i++)

    $zeile = $resultlist[$i]+1;

      
    was für einen Typ haben die Elemente von resultlist[]? Nach deiner Beschreibung müsste man vermuten, es seien Strings.  
      
    
    > Hätte ich statt $zeile $resultlist[$i]+1 eingefügt, wäre die Ausgabe pro Zeile immer 1 gewesen.  
      
    Ups. Dann müsste $resultlist[$i] durchgehend ein Leerstring sein. Das hört sich nicht wirklich schlüssig an.  
      
    
    > Ich versuchte Lösungen wie ((int)$resultlist[$i])++, half aber nichts.  
      
    Das hätte es nach meinem Verständnis eigentlich bringen sollen ...  
      
    
    > Seltsamerweise lieferte ++$resultlist[$i] zwar die richtige Zeilennummer, d.h. hier wurde plötzlich ein int erkannt, jedoch bedeutet das natürlich, dass die Variable postinkrementiert wird  
      
    Nein, prä-incrementiert. Post-increment (erst lesen, dann incrementieren) wäre es, wenn der Operator ++ hinter dem Operanden steht.  
      
    Ich mache in so einem Fall -also wenn ich eine numerische Interpretation erzwingen will- immer eine Operation, die nur für numerische Werte definiert ist. Beispielsweise eine Multiplikation mit 1:  
      
    
    >       $zeile = $resultlist[$i]\*1 + 1;  
      
    That does the trick.  
      
    Ciao,  
     Martin  
    
    -- 
    Die letzten Worte des stotternden Beifahrers:  
    Frei... frei... frei... freilich kommt da was!!  
    
    
    1. Hi!

      Ich mache in so einem Fall -also wenn ich eine numerische Interpretation erzwingen will- immer eine Operation, die nur für numerische Werte definiert ist. Beispielsweise eine Multiplikation mit 1:

      $zeile = $resultlist[$i]*1 + 1;
      That does the trick.

      In diesem Fall. Es soll aber darum gehen, dies nicht alleinstehend zu berechnen sondern auch noch vorn und hinten stringverknüpft werden. Wenn du 1 multiplizierst machst du damit nur einen schlechter erkennbaren impliziten händischen Typecast, aber aufgrund der drumherum stehen sollenden Stringverknüpfung ändert sich im Wesentlichen nichts an der Abarbeitungsreihenfolge.

      Lo!

      1. Hallo,

        $zeile = $resultlist[$i]*1 + 1;
        That does the trick.
        In diesem Fall. Es soll aber darum gehen, dies nicht alleinstehend zu berechnen sondern auch noch vorn und hinten stringverknüpft werden.

        ja, stimmt. Was Markus wirklich wollte, habe ich aber erst begriffen, als ich deinen Beitrag gelesen habe. Mir war nicht klar, dass er die Zeilen

        $zeile = $resultlist[$i]+1;
          echo 'Zeile ' . $zeile . ': ' . $filecontent[$resultlist[$i]] . '<br />';

        eigentlich zusammenfassen wollte, sondern ich habe die erste der beiden Zeilen isoliert als Problem betrachtet. Daher auch mein Unverständnis, dass er mit dem Pre- oder Postincrement-Operator ebensowenig glücklich wurde, wie mit dem expliziten Typecast.

        aufgrund der drumherum stehen sollenden Stringverknüpfung ändert sich im Wesentlichen nichts an der Abarbeitungsreihenfolge.

        Ja, wenn man den Kontext mal verstanden hat ...

        Markus, wenn du wieder mal so einen Fall hast, dann gib doch bitte die Variante des Quellcodes wieder, die das Problem aufweist, nicht den Workaround!

        So long,
         Martin

        --
        Ungeschehene Ereignisse können einen katastrophalen Mangel an Folgen nach sich ziehen.
          (Unbekannter Politiker)
  2. Hi!

    for ($i = 0; $i < count($resultlist); $i++)  {

    $zeile = $resultlist[$i]+1;
                     echo 'Zeile ' . $zeile . ': ' . $filecontent[$resultlist[$i]] . '<br />';
                }

    
    >   
    > Hätte ich statt $zeile $resultlist[$i]+1 eingefügt, wäre die Ausgabe pro Zeile immer 1 gewesen. Die richtige Ausgabe wäre $resultlist[$i] plus 1.  
    > Ich versuchte Lösungen wie ((int)$resultlist[$i])++, half aber nichts.  
      
    Wenn das ++ hinten steht, wird die Inkrememtierung erst nach der Rückgabe des Wertes vorgenommen. In der Ausgabe landet also $resultlist[$i] und wenn du dir nach der Schleife den Inhalt des Arrays $resultlist ausgeben lässt, siehst du auch, wo die Inkrementierung geblieben ist.  
      
    
    > Seltsamerweise lieferte ++$resultlist[$i] zwar die richtige Zeilennummer, d.h. hier wurde plötzlich ein int erkannt,  
      
    Nein, es wird kein int erkannt sondern es findet eine automatische Typumwandlung statt. ++ ist ein arithmetischer Operator, also wird eine Typkonvertierung in Richtung Zahl vorgenommen. Die Ausgabe ist ein String-Kontext, also wird nach der Berechnung das Ergebnis nach String konvertiert.  
      
    
    > jedoch bedeutet das natürlich, dass die Variable postinkrementiert wird, was ich in diesem Fall aber nicht will.  
      
    Du meinst, dass sie hinterher inkrementiert ist (was etwas anderes als postinkrementiert ist). Ob das ++ vor oder nach der Variable steht ist für den unmittelbaren Zugriff auf die Variable interessant, insofern als dass der Wert einmal schon inkrementiert ist, und andererseits erst nach dem Zugriff erhöht wird. Irgendwann hinterher ist dann der Wert immer erhöht.  
      
    
    > Wie geht PHP hier vor? Wieso wird einmal ein int, dann wieder ein String erkannt,  
      
    [Operatoren-Rangfolge](http://de2.php.net/manual/en/language.operators.precedence.php) ist das Stichwort. + und . haben den gleichen Rang. Das heißt, dass schrittweise von links nach rechts ausgewertet wird. Bei  
      
    `echo 'Zeile ' . $resultlist[$i] + 1 . ': ' . $filecontent[$resultlist[$i]] . '<br />';`{:.language-php}  
      
    wird 'Zeile ' und $resultlist[$i] stringverknüpft. Anschließend soll eine 1 hinzuaddiert werden, also wird der String 'Zeile ...' in eine Zahl konvertiert, was 0 ergibt. 1 addiert ergibt 1. Dann kommt mit ». ': '« wieder ein String-Kontext, also wird die 1 in einen String konvertiert und mit dem Nachfolgenden verknüpft.  
      
    
    > und wie könnte ich es ohne eine Zusatzvariable lösen?  
      
    Indem du die Auswertereihenfolge explizit vorgibst:  
      
    `echo 'Zeile ' . ($resultlist[$i] + 1) . ': ' . $filecontent[$resultlist[$i]] . '<br />';`{:.language-php}  
      
      
    Lo!
    
    1. Hallo,

      Du meinst, dass sie hinterher inkrementiert ist (was etwas anderes als postinkrementiert ist). Ob das ++ vor oder nach der Variable steht ist für den unmittelbaren Zugriff auf die Variable interessant, insofern als dass der Wert einmal schon inkrementiert ist, und andererseits erst nach dem Zugriff erhöht wird. Irgendwann hinterher ist dann der Wert immer erhöht.

      Ich meinte natürlich pre-inkrement. Obwohl darüber noch nachdachte, schrieb ich genau die verkehrte Bezeichnung hin.

      ($resultlist[$i] + 1)

      So funktioniert die ganze Sache. (Wieso ich auf Klammernsetzung nicht selbst draufkam...)

      Danke und Grüße,
      Markus