WernerK: Mehrere Bedingungen abfragen schlägt fehl

Hallo
es ist mir fast ein wenig peinlich das zu fragen. Es ist ja nicht so das ich das zum ersten mal mache. Aber aus irgend einem Grund klappt eine IF Abfrage mit mehreren Bedingungen nicht.
Vielleicht steht mir auch heute nur einer auf der Leitung :-)
Ich lese mit fgetcsv eine CSV Datei ein und möchte dann zuerst du Struktur überprüfen, das sich hier nichts ändert. Die erste Zeile ist der Kopf mit den Spaltenbeschriftungen

Spalte1 Spalte2 Spalte3

Wenn nun eine CSV Datei mit genau dieser Struktur geladen wird, schlägt die Prüfung fehl. Es kommt immer die Ausgabe "CSV Struktur stimmt nicht"

  
while (($csv_line = fgetcsv($fp, filesize("test.csv"), "\t")) !== FALSE){  
if (!$firstline) {//erste Zeile überspringen  
   //weitere Schritte mit CSV Daten  
}  
else{  
  //erste Zeile  
  if( $csv_line[0] == "Spalte1" AND $csv_line[1] == "Spalte2"  AND $csv_line[2] == "Spalte3"  ){  
    echo "ALLES OK <br>";  
  }else{  
    echo "CSV Struktur stimmt nicht <br>";  
    break;  
 }  
  
}  

Gruss
Werner

  1. Hi,

    if( $csv_line[0] == "Spalte1" AND $csv_line[1] == "Spalte2"  AND $csv_line[2] == "Spalte3"  ){

    echo "ALLES OK <br>";
      }else{
        echo "CSV Struktur stimmt nicht <br>";
        break;
    }

      
    ich würde mal das ausgeschriebene AND durch den Operator && austauschen. Beide machen zwar eine Und-Verknüpfung, stehen aber in der Rangfolge der Operatoren an verschiedenen Positionen. Tückische PHP-Stolperfalle.  
      
    Ciao,  
     Martin  
    
    -- 
    [why the heck](http://community.de.selfhtml.org/zitatesammlung/zitat175) do you jerk think, that wir ein doppelposting nicht bemerken, wenn you zwischendurch the sprache wechselst?  
      (wahsaga)  
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    
    1. Hallo
      danke für den Tipp.
      brachte aber leider auch mit && keine Änderung.

      Gruss
      Werner

    2. Tach!

      if( $csv_line[0] == "Spalte1" AND $csv_line[1] == "Spalte2"  AND $csv_line[2] == "Spalte3"  ){
      ich würde mal das ausgeschriebene AND durch den Operator && austauschen. Beide machen zwar eine Und-Verknüpfung, stehen aber in der Rangfolge der Operatoren an verschiedenen Positionen. Tückische PHP-Stolperfalle.

      Das stimmt zwar, aber beide liegen unterhalb der Vergleichsoperatoren. Das Problem tritt lediglich bei Zuweisungen und ?: auf.

      Jedenfalls ist so direkt nicht zu erkennen, woran es scheitert. Kontrollausgaben mit var_dump() können erleuchtend sein.

      dedlfix.

      1. Hallo,

        habe nun mal ein var_dump zur Kontrolle eingebaut

        ..
        }else{
        echo var_dump($csv_line[0]) . "<br>";
        echo var_dump($csv_line[1]) . "<br>";
        echo var_dump($csv_line[2]) . "<br>";

        echo "Achtung!! Die CSV Struktur stimmt...
        break;
        }

        Die Ausgabe ist immer String
        string(10) "Spalte1"
        string(7) "Spalte2"
        string(7) "Spalte3"

        Gruss
        Werner

        1. Hi,

          Die Ausgabe ist immer String

          ja sicher, aber ...

          string(10) "Spalte1"
          string(7) "Spalte2"
          string(7) "Spalte3"

          ... dass der erste String eine Länge von 10 Zeichen ... äh, Bytes hat, macht dich nicht stutzig?
          Da werden wohl doch noch irgendwelche lustigen Steuerzeichen drinstecken. Eventuell eine BOM, die am Anfang der CSV-Datei steht?

          Ciao,
           Martin

          --
          Programmierer (m), seltener auch P~in (w):
          Irdische, i.a. humanoide Lebensform, die in einem komplizierten biochemischen Prozess Kaffee, Cola und Pizza in maschinenlesbaren Programmcode umwandelt.
          P~ bilden gelegentlich mit ihresgleichen kleine Gruppen, sogenannte Communities, sind aber ansonsten meist scheue Einzelgänger.
          P~ sind vorwiegend nachtaktiv und ohne technische Hilfsmittel nur eingeschränkt lebensfähig.
          Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
          1. Hallo

            ... dass der erste String eine Länge von 10 Zeichen ... äh, Bytes hat, macht dich nicht stutzig?
            Da werden wohl doch noch irgendwelche lustigen Steuerzeichen drinstecken. Eventuell eine BOM, die am Anfang der CSV-Datei steht?

            oh mann ja klar. Wer lesen kann ist klar im Vorteil :-)

            Da war wirklich noch ein BOM vorne dran. (Das war aber auch gemein)

            habe es jetzt so hinbekommen:
            if (0 === strpos($csv_line[0], "\xEF\xBB\xBF")) {
            echo "BOM GEFUNDEN >BR>";
            $csv_line[0] = substr($csv_line[0], 3);
            }

            Danke euch allen

            Gruss
            Werner }

      2. Hallo,

        ich würde mal das ausgeschriebene AND durch den Operator && austauschen. Beide machen zwar eine Und-Verknüpfung, stehen aber in der Rangfolge der Operatoren an verschiedenen Positionen. Tückische PHP-Stolperfalle.
        Das stimmt zwar, aber beide liegen unterhalb der Vergleichsoperatoren. Das Problem tritt lediglich bei Zuweisungen und ?: auf.

        ah, danke für die Klarstellung. Ich erinnere mich nicht mehr an Einzelheiten, aber ich entsinne mich, dass ich damit vor längerer Zeit mal auf die Schnauze gefallen bin.

        Ciao,
         Martin

        --
        Jungs sind wie Waschmaschinen: Wenn man sie anmacht, kommen sie ins Schleudern.
        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
        1. Tach!

          [AND vs. &&] Tückische PHP-Stolperfalle.
          Das stimmt zwar, aber beide liegen unterhalb der Vergleichsoperatoren. Das Problem tritt lediglich bei Zuweisungen und ?: auf.
          Ich erinnere mich nicht mehr an Einzelheiten, aber ich entsinne mich, dass ich damit vor längerer Zeit mal auf die Schnauze gefallen bin.

          Ja, ich auch.

          $foo = bedingung1 AND bedingung2;

          In $foo steht immer das Ergebnis des Ausdrucks bedingung1. bedingung2 wird anscheinend ignoriert. Finde mal darin die Ursache für den Programmfehler!

          Es wird nämlich so berechnet:

          ($foo = bedingung1) AND bedingung2;

          Der Zuweisungsoperator = hat einen höheren Rang als das AND. bedingung 2 wird zwar berechnet, wenn wegen des Kurzschlussverfahrens die Zuweisung nicht bereits false ergeben hat, aber das Ergebnis verpufft. Klammern setzen

          $foo = (bedingung1 AND bedingung2);

          oder die Verwendung von && führt zum gewünschten Ergebnis.

          dedlfix.

  2. Moin
    So, mal dumm von mir gefragt

    while (($csv_line = fgetcsv($fp, filesize("test.csv"), "\t")) !== FALSE){
    if (!$firstline) {//erste Zeile überspringen

      
    wann und wo wird firstline gesetzt? Mach hier mal ne Ausgabe rein und du wirst die immer erhalten, da dies immer wahr ist, da firstline nicht gesetzt ist. Soll heißen, er springt immer in diesen Zweig der Alternative!  
      
    
    > ~~~php
      
    
    >    //weitere Schritte mit CSV Daten  
    > }  
    > else{  
    > 
    
    

    hier springt er NIE rein. Damit wird alles folgende NIE ausgeführt

    //erste Zeile
      if( $csv_line[0] == "Spalte1" AND $csv_line[1] == "Spalte2"  AND $csv_line[2] == "Spalte3"  ){
        echo "ALLES OK <br>";
      }else{
        echo "CSV Struktur stimmt nicht <br>";
        break;
    }

    }

      
    Wenn du uns keinen Code unterschlagen hast, ist dies der Grund für das Scheitern der Alternative und nicht die Verkettung!  
      
    Gruß Bobby  
    
    -- 
    -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-  
    ### Henry L. Mencken ###  
    -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-  
    ### Viktor Frankl ###  
      
    ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
    
    1. Hallo
      sorry, ich hatte nur den PHP Code ab der While Schleife gezeigt.
      vorher wird hier natürlich "firstline" gesetzt.
      Also es ist schon definitiv die richtige Zeile mit Nr1.
      Meine Kontrollausgaben zeigen die Spaltenbeschriftungen ja auch richtig an.

        
      $firstline = true;  
      while (($csv_line = fgetcsv($....  {  
        
      if (!$firstline) {  
        //weitere bearbeitung  
      }  
      else{  
      //erste Zeile  
        
      //mein CSV Spalten Vergelich  
        if( $csv_line[0] == "Spalte1" AND $csv_line[1] == "Spalte2"  AND $csv_line[2] == "Spalte3"  ){  
          echo "ALLES OK <br>";  
         }else{  
          echo "Die CSV Struktur stimmt nicht überein! es gibt -" . $csv_line[0] ."- und -" .  $csv_line[1] . "- und -" . $csv_line[2] . "- <br>";  
          break;  
        }  
      }//if (!$firstline) {  
        $firstline = false;  
      }//while  
      
      

      Gruss
      Werner

  3. Hallo
    [] Die erste Zeile ist der Kopf mit den Spaltenbeschriftungen

    Spalte1 Spalte2 Spalte3

    Wenn nun eine CSV Datei mit genau dieser Struktur geladen wird, schlägt die Prüfung fehl. Es kommt immer die Ausgabe "CSV Struktur stimmt nicht"

    Dein

    }else{
        echo "CSV Struktur stimmt nicht <br>";
        break;
    }

    liegt innerhalb der Schleife. Du kommst dahin, weil selbst im Fall, dass die Struktur (Überschriften in der ersten Zeile) stimmt, Deine Schleife weiterläuft.

    Rührt Euch ;)

  4. Hi,

    Wenn nun eine CSV Datei mit genau dieser Struktur geladen wird, schlägt die Prüfung fehl. Es kommt immer die Ausgabe "CSV Struktur stimmt nicht"

    //erste Zeile
      if( $csv_line[0] == "Spalte1" AND $csv_line[1] == "Spalte2"  AND $csv_line[2] == "Spalte3"  ){

      
    Na dann kontrolliere vor dieser Zeile als erstes mal, ob diese Variablen \*tatsächlich\* diese Werte enthalten:  
      
    `var_dump($csv_line[0], $csv_line[0] == "Spalte1", $csv_line[1], $csv_line[1] == "Spalte2", $csv_line[2], $csv_line[2] == "Spalte3");`{:.language-php}  
      
    Was kommt da raus?  
      
    MfG ChrisB  
      
    
    -- 
    Autocomplete has spoiled me to a point where it happens every so often that I encounter a CAPTCHA, and I just type in the first character … and then wait for the rest of the code to be automatically suggested :/
    
    1. Hallo

      Na dann kontrolliere vor dieser Zeile als erstes mal, ob diese Variablen *tatsächlich* diese Werte enthalten:

      var_dump($csv_line[0], $csv_line[0] == "Spalte1", $csv_line[1], $csv_line[1] == "Spalte2", $csv_line[2], $csv_line[2] == "Spalte3");

      Was kommt da raus?

      Dies Ergebnis:
      string(10) "Spalte1" bool(false) string(7) "Spalte2" bool(true) string(7) "Spalte3" bool(true)

      Offensichtlich ist das Erste "false"
      Aber warum? Der String "Spalte1" stimmt doch?

      Gruss
      Werner

      1. Moin

        Offensichtlich ist das Erste "false"
        Aber warum? Der String "Spalte1" stimmt doch?|

        Hast du evtl nen BOM drin?

        Gruß Bobby

        --
        -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
        ### Henry L. Mencken ###
        -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
        ### Viktor Frankl ###
        ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
        1. Hakuna matata!

          Hast du evtl nen BOM drin?

          Sehr wahscheinlich sogar, deshalb zeigt var_dump() bei der Stringlänge auch 10 und nicht 7 an.

          string(10) "Spalte1"

          --
          “All right, then, I'll go to hell.” – Huck Finn
          1. Hallo,

            Hast du evtl nen BOM drin?

            Sehr wahscheinlich sogar, deshalb zeigt var_dump() bei der Stringlänge auch 10 und nicht 7 an.

            string(10) "Spalte1"

            Kann man dem mit einem trim abhelfen? Hab grade keine BOM zur Hand...

            Gruß
            Kalk

            1. Moin

              Kann man dem mit einem trim abhelfen? Hab grade keine BOM zur Hand...

              Also hab mir folgende Lösung zurecht gebastelt:

              $bom = pack('H*','EFBBBF');  
              $str = preg_replace("/^$bom/", '', $str);
              

              Evtl. gehts auch eleganter.

              Gruß Bobby

              --
              -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
              ### Henry L. Mencken ###
              -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
              ### Viktor Frankl ###
              ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
              1. Hallo,

                darf ich nochmals nachfragen wegen dem BOM bzw. pack();

                Also hab mir folgende Lösung zurecht gebastelt:

                $bom = pack('H*','EFBBBF');

                $str = preg_replace("/^$bom/", '', $str);

                  
                Ich habe mir das Manual zu pack() eben mal angeschaut.  
                So ganz habe ich es nicht verstanden. Die Funktion wandelt nicht sichtbare Zeichen oder Daten in eine Zeichenkette um?  
                  
                Was bedeutet denn "oberer Halbwert zuerst" ?  
                  
                H 	Hex-Zeichenkette, oberer Halbwert zuerst  
                  
                Könnte man nicht direkt mit preg\_replace das BOM entfernen?  
                  
                preg\_replace("/^\xEF\xBB\xBF/", '', $str);  
                  
                  
                Gruss  
                Werner
                
                1. @@WernerK:

                  nuqneH

                  Was bedeutet denn "oberer Halbwert zuerst" ?

                  Was bedeutet denn BOM?

                  Qapla'

                  --
                  „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
                2. Tach!

                  Könnte man nicht direkt mit preg_replace das BOM entfernen?
                  preg_replace("/^\xEF\xBB\xBF/", '', $str);

                  Kann man, und das halte ich auch so für besser als noch eine weitere Funktion aufzurufen, die relativ ungebräuchlich und nicht so einfach verständlich ist.

                  $bom = pack('H*','EFBBBF');
                  $str = preg_replace("/^$bom/", '', $str);

                  Das direkte Notieren ist auch ausführtechnisch einfacher. In der pack-Zeile muss der PHP-Syntax-Parser das Stringliteral erkennen und zu einem 6-Zeichen-String verarbeiten. Dann der Aufruf von pack() und diese Funktion muss die 6 Zeichen nochmal interpretieren und dann entsprechend H* in 3 Bytes konvertieren. Notiert man die Zeichen als Escape-Sequenz direkt in den String der preg_replace-Funktion (oder meinetwegen auch in eine Hilfsvariable), dann muss da nur der PHP-Parser die Zeichen erkennen und kann die 3 Byte auf direktem Wege erstellen.

                  dedlfix.

            2. Hakuna matata!

              Kann man dem mit einem trim abhelfen? Hab grade keine BOM zur Hand...

              Nein, trim entfernt nur folgende Zeichen:

              " " (ASCII 32 (0x20)), an ordinary space.
              "\t" (ASCII 9 (0x09)), a tab.
              "\n" (ASCII 10 (0x0A)), a new line (line feed).
              "\r" (ASCII 13 (0x0D)), a carriage return.
              "\0" (ASCII 0 (0x00)), the NUL-byte.
              "\x0B" (ASCII 11 (0x0B)), a vertical tab.

              Man könnte auf die Idee kommen, den zweite Parameter von (l)trim zu nutzen, um die BOM zu entfernen, etwa so:

              $string = ltrim( $string , "\xEF\xBB\xBF"); // UTF-8 BOM

              Das wird aber nicht ordentlich funktionieren, denn ltrim() wird nach jedem dieser Bytes einzeln suchen und würde auch ein einsames "\0xBB" am Anfang eines Strings abschneiden. In einem Unicode-String ohne BOM wäre das aber das Zeichen: »

              --
              “All right, then, I'll go to hell.” – Huck Finn
  5. @@WernerK:

    nuqneH

    ~~~php

    if( $csv_line[0] == "Spalte1" AND $csv_line[1] == "Spalte2"  AND $csv_line[2] == "Spalte3"  ){

    echo "ALLES OK <br>";
      }else{
        echo "CSV Struktur stimmt nicht <br>";
        break;
    }

      
    Vernünftige Ausgaben wären `<p>Alles OK</p>`{:.language-html} und `<p>CSV-Struktur stimmt nicht</p>`{:.language-html}:  
      
    Großschreibung (so überhaupt sinnvoll) wäre [Sache von CSS](http://forum.de.selfhtml.org/archiv/2009/7/t188567/#m1255902).  
      
    Bindestrich, [kein Deppenleerzeichen](https://de.wikipedia.org/wiki/Leerzeichen_in_Komposita).  
      
    Und vergiss, dass es in HTML ein br-Element gibt (wenn du nicht gerade Postadressen, Verse o.ä. auszeichnest.)  
      
    Qapla'
    
    -- 
    „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
    
    1. Hallo

      Vernünftige Ausgaben wären <p>Alles OK</p> und <p>CSV-Struktur stimmt nicht</p>:

      Danke für den Hinweis. Das sind jedoch nur für mich während der Entwicklung oder Testphase Hilfsmittel gewesen.
      Später kommt das natürlich nicht mehr vor, bzw. kommen andere Meldungen.

      Gruss
      Werner