Sir Ulli: @ - Fehlerausgabe unterdrücken

Normalerweise kann man mit einem @ ja die Fehlerausgabe unterdrücken.
Wie funktioniert das bei einer foreach-Schleife.

Also wenn mir die Zeile
     foreach ($bbb as $line_num => $line) {
einen Fehler ausgibt?

gruss
Ulli

  1. Hallo!

    Also wenn mir die Zeile
         foreach ($bbb as $line_num => $line) {
    einen Fehler ausgibt?

    Wenn hier ein Fehler auftritt, dann hast du wohl irgendwo einen Fehler. :-)
    Überprüfe vorher, ob $bbb auf wirklich ein Array ist und führe nur dann die foreach Schleife durch.

    mfg
      frafu

  2. Hallo erstmal!

    foreach ($bbb as $line_num => $line)

    abhängig vom zu erwartenden Fehler setzt man foreach() in ein if-Anweisung. Beispiel:

      
    if(isset($bbb) && is_array($bbb))  
          foreach ($bbb as $line_num => $line);  
    
    

    Gruß aus Berlin!
    eddi

  3. Hallo Ulli,

    Normalerweise kann man mit einem @ ja die Fehlerausgabe unterdrücken.

    Ja, aber das ist kein guter Stil. Du solltest generell lieber mögliche Fehler im Script abfangen, anstatt die Fehlermeldung einfach zu unterdrücken.

    Schöne Grüße,

    Johannes

    1. Hallo Johannes,

      Normalerweise kann man mit einem @ ja die Fehlerausgabe unterdrücken.

      Ja, aber das ist kein guter Stil. Du solltest generell lieber mögliche Fehler im Script abfangen, anstatt die Fehlermeldung einfach zu unterdrücken.

      warum ist das kein guter Stil?

      Gruß aus Berlin!
      eddi

      1. Moin!

        Normalerweise kann man mit einem @ ja die Fehlerausgabe unterdrücken.

        Ja, aber das ist kein guter Stil. Du solltest generell lieber mögliche Fehler im Script abfangen, anstatt die Fehlermeldung einfach zu unterdrücken.

        warum ist das kein guter Stil?

        Weil du damit -- wie gesagt -- lediglich die Fehlermeldung unterdrückst, aber nicht den Fehler. Stell dir z.B. einmal folgendes vor (beliebter Einsteigerfehler):

        $fh = @fopen('/pfad/zu/1/Datei', 'r');  
            // schlägt fehl, bleibt allerdings unbemerkt -> wegen @  
          
        // benutze @fgets, weil dies ab und zu Fehler produziert  
        while ($line = @fgets($fh)) {  
            tueEtwasMit($line);    // was passiert hier?  
        }  
          
        @fclose($fh);
        

        Preisfrage: Was passiert in der Funktion tueEtwasMit() mit $line als Argument, wie sieht $line überhaupt aus, wird die while-Schleife überhaupt durchlaufen, wie reagiert dein Programm?
         -- Deshalb ist es besser, zusätzlich sämtliche Fehler abzufangen und Rückgabewerte zu prüfen, weil du dann _meistens_ weißt, was passiert.

        Viele Grüße,
        Robert

        1. Moi moin,

          Weil du damit -- wie gesagt -- lediglich die Fehlermeldung unterdrückst, aber nicht den Fehler. Stell dir z.B. einmal folgendes vor (beliebter Einsteigerfehler):

            
          $fh = @fopen('/pfad/zu/1/Datei', 'r');  
          while ($line = @fgets($fh))  
             // AUA!¹  
             tueEtwasMit($line);    // was passiert hier?  
          @fclose($fh);
          
          1. Dann will ich mal hoffen, daß der Inhalt des Files nicht aus "false" oder "0" besteht, sonst wird nach Deinem Bespiel nichts verarbeitet.
            
          $d='/pfad/zu/1/Datei';  
          $c=filesize($d);  
          if(is_resource($f=@fopen($d,'r'))){  
             while(!feof($f))  
                tueEtwasMit(fgets($f,$c));  
             fclose($f);  
          }  
          else mach_was_anderes();
          

          -- Deshalb ist es besser, zusätzlich sämtliche Fehler abzufangen und Rückgabewerte zu prüfen, weil du dann _meistens_ weißt, was passiert.

          Dem stimme ich zu. Da Fehlermeldungen nur beim Debuggen sinnvoll sind, wird man entweder die Fehlermeldungen im Programm mittel "@" oder durch Konfiguration unterdrücken. Genau das macht mein Beispiel.

          Dies stellt aber keine Begründung dar, warum nun "@" vermieden werden sollte. Ganz im Gegenteil geben Fehlermeldungen PHPs zum Teil Informationen für mögliche Angriffe preis. Weiterhin gebe ich auch zu bedenken, daß -ob mit "@" oder ohne- die weitere Programmausführung nicht beeinflußt wird. "@" tut also an dem von Dir thematisiertem Punkt rein gar nichts zur Sache.
           Im Sinne von Stil also Guter Stil™, hätte ich Konfiguration statt "@" akzeptiert - schlampige Programmierung hingegen akzeptiere ich als Begründung nicht.

          Gruß aus Berlin!
          eddi

          1. Hallo eddi,

            Im Sinne von Stil also Guter Stil™, hätte ich Konfiguration statt "@" akzeptiert - schlampige Programmierung hingegen akzeptiere ich als Begründung nicht.

            @ ist vielleicht nicht direkt schlampig, führt aber sehr schnell dazu. Insbesondere da es mühsam ist, immer eine Test-Version ohne und eine Produktivversion mit @ aktuell zu halten. Es gibt meiner Meinung nach praktisch keinen sinnvollen Grund für diesen Operator; wie du schon erkannt hast, regelt man das besser über die Konfiguration.

            Außerdem sollte man auch auf einem Produktivsystem Fehlermeldungen nicht einfach unterdrücken, sondern lediglich nicht an den Client ausgeben lassen. Eine Ausgabe in ein Logfile ist sehr hilfreich wenn man bei Besuchern aufgetretene Fehler reproduzieren möchte.

            Schöne Grüße,

            Johannes

            1. Nabend,

              dann sind wir uns darüber einig, daß der mahnend erhobene Finger plus (ordentlicher) Begründung eine größere Hilfe ist? ;)

              Gruß aus Berlin!
              eddi

            2. echo $begrüßung;

              Es gibt meiner Meinung nach praktisch keinen sinnvollen Grund für diesen Operator;

              Da kann ich einen liefern. Wenn man wissen möchte, ob eine Datei ein Bild vom Typ jpeg, gif, png, ... enthält, kann man getimagesize($filename) verwenden. Als Rückgabewert erhält man entweder ein Array oder false. Das kann man ja prüfen (das sollte man sowieso mit solchen Entweder-Oder-Rückgabewerten) und je nachdem weiter verfahren. Dummerweise gibt es immer eine Warnung, wenn die Funktion einen Anlass hat, false zurückzugeben.

              $filename = '...';  
              if ($imageinfo = @getimagesize($filename))  
                printf('Abmessungen: %s x %s Pixel; Typ: %s',  
                  $imageinfo[0],  
                  $imageinfo[1],  
                  $imageinfo['mime']);  
              else  
                printf('%s ist keine Bilddatei', htmlspecialchars($filename));
              

              Falls jemand meint, einen Fehler gefunden zu haben: Das = in der if-Anweisung ist richtig. Es handelt sich um eine Zuweisung, nicht um einen Vergleich (==). Das Ergebnis einer Zuweisung ist der Wert der Zuweisung. Das "if" bekommt also entweder das oben erwähnte Array (welches nicht leer ist und damit als true angesehen wird) oder ein false zu sehen.

              echo "$verabschiedung $name";

              1. Hi,

                if ($imageinfo = @getimagesize($filename))

                Ohne zu testen:

                if($imageinfo=getimagesize($filename) && !empty($imageinfo))

                oder

                ... is_array($imageinfo) ...

                oder ...

                ... oder auch einfach darunter eine weitere if-Abfrage auf Plausibilität.

                Ich benutze zwar durchaus auch @, aber nicht in *solch* einem Fall. Das ist doch schlechter Stil! ;-)

                Gruß, Cybaer

                --
                Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
                1. Hi Ingrid ;-),

                  Ich benutze zwar durchaus auch @, aber nicht in *solch* einem Fall. Das ist doch schlechter Stil! ;-)

                  Nach einem kurzen Nachdenken, ziehe ich meinen Einwand zurück - ich verwende @ in der Tat übrigens auch für den gleichen Zweck. Zwar nicht bei getimagesize(), da ich die Datein vorher auf Plausibilität teste - die Dateigröße muß ohnehin >12 Bytes sein, da getimagesize() sonst ggf. die Grätsche macht (auf jeden Fall aber nicht sinnvoll ist), aber bei der Dateiüberprüfung. Und da tritt natürlich das gleiche Problem zutage, was sinnigerweise mit @ abgefangen wird ... >8->

                  Gruß, Cybaer

                  --
                  Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
                2. Hallo,

                  das Beispiel dedlfix' sagt mir zwar auch nicht viel, es gibt aber für Netzwerkverbindungen (die einen TimeOut haben) bei Dämonprogrammierung keine Alternative zu "@":

                    
                  $c=stream_socket_server('tcp://0.0.0.0:80');  
                  while(1){  
                     if(is_resource($s=@stream_socket_accept($c)){  
                        lies_aus_verbindung();  
                        schreib_in_verbindung();  
                     }  
                  }
                  

                  Gruß aus Berlin!
                  eddi

                  1. Hi,

                    das Beispiel dedlfix' sagt mir zwar auch nicht viel,

                    Och, mir schon. Aber man sollte drüber nachdenken, *bevor* man was dazu schreibt! >;->

                    Überhaupt morgens ... =;-)

                    Gruß, Cybaer

                    --
                    Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
                3. echo $begrüßung;

                  if ($imageinfo = @getimagesize($filename))

                  Ohne zu testen:
                  if($imageinfo=getimagesize($filename) && !empty($imageinfo))
                  oder
                  ... is_array($imageinfo) ...

                  Alles schön und gut (bzw. nicht, s.u.). Das Problem ist nur, dass getimagesize() zusätzlich zu dem Rückgabeergebnis false noch eine extra Warnung wirft, wenn es kein Bilddateinamen übergeben bekommen hat.
                  Auch mysql_connect() wirft im Fehlerfall eine Warnung. Diese Warnungen stören meist das Layout oder den Inhalt der Seite. Es gilt es also, zusätzlich zum Auswerten des Rückgabewertes die Ausgabe der Warnung unterdrücken, damit man dem Anwender eine hilfreichere Tröstmeldung oder eine Alternative präsentieren kann.
                  mysql_query() verhält sich im Gegensatz zu mysql_connect() ruhig, wenn bei der Ausführung ein Fehler auftritt. Voraussetzung ist allerdings, dass es nicht zu einem Folgefehler wegen des nicht erfolgreichen Connects kommt, sonst gibt es ebenfalls eine Warnung. Da man aber ordentlich programmiert hat, hat man ja den Fehler weiter oben schon abgefangen und es kommt gar nicht soweit ...
                  Für mysql_query() braucht man also den @-Operator nicht unbedingt. (Vielleicht für den bei Wald- und Wiesen-Scripts eher weniger wahrscheinlichen Fall, dass die Verbindung zwischen Connect und Query ausfällt.)

                  Es gibt also mindestens 2 sinnvolle Anwendungsfälle für den @-Operator.

                  if($imageinfo=getimagesize($filename) && !empty($imageinfo))

                  Die Prüfung auf !empty($imageinfo) ist überflüssig. getimagesize() liefert entweder false oder ein nicht leeres Array. Nicht leere Arrays werden durch PHPs impliziten Typecast zu true. if bekommt also entweder true oder false zu sehen. Damit hat man eine Aussage, ob es sich um ein von getimagesize() unterstütztes Bildformat handelt oder nicht.

                  if (is_array($imagesize = @getimagesize(...)))
                      ...

                  oder meinetwegen auch in zwei Schritten

                  $imagesize = @getimagesize(...);
                    if (is_array($imagesize))
                      ...

                  bringt das gleiche Ergebnis wie meine Variante nur dass hier noch ein zusätzlicher Funktionsaufruf (is_array()) erfolgt. Und wenn man es weiter (über-)treiben will kann man das Ergebnis auch noch mit true vergleiche:

                  if (is_array($imagesize) == true)
                      ...

                  echo "$verabschiedung $name";

                  1. Hi,

                    Es gilt es also, zusätzlich zum Auswerten des Rückgabewertes die Ausgabe der Warnung unterdrücken,

                    Bei mir sind für den User die PHP-Fehlermeldungen/Warnungen prinzipiell nicht sichtbar, sie werden nur protokolliert. Sie sind nur für den/die Entwickler zu sehen, die sich dann auch nicht am ggf. kaputten Design stören, da es ihre Aufgabe ist, dafür zu sorgen, daß diese Meldung eben nicht auftritt. :)

                    Soviel als Defaulteinstellung.

                    Im Einzelfall läßt sich dann konfigurieren, wer Entwickler-Status hat, wer (Content-)Manager-Status oder wer gar keinen besonderen Status hat (=User) und welche Gruppe was an PHP-Meldungen sieht oder eine Protokollierung in welches Log auslöst. :-)

                    Gruß, Cybaer

                    --
                    Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
                    1. echo $begrüßung;

                      Es gilt es also, zusätzlich zum Auswerten des Rückgabewertes die Ausgabe der Warnung unterdrücken,

                      Bei mir sind für den User die PHP-Fehlermeldungen/Warnungen prinzipiell nicht sichtbar, sie werden nur protokolliert. Sie sind nur für den/die Entwickler zu sehen, [...]
                      Soviel als Defaulteinstellung.

                      Das sehe ich so auch als sinnvoll an.
                      Man muss nur berücksichtigen, dass nicht jeder die Möglichkeit eingeräumt bekommt, die PHP-Konfiguration nach eigenem Gusto einzustellen. Wenn man also Wert darauf legt, dass das eigene Script auf möglichst vielen Systemen ordentlich lauffähig ist, ...

                      error_reporting(0) am Anfang eines in der Produktivumgebung laufenden Scripts wäre auch noch eine Möglichkeit (wenn man nicht ständig vergessen würde, das bei jedem Upload anzupassen ... (Gut, man könnte sich auch mit dem Includen einer Datei behelfen, die die auf dem Produktivsystem gewünschten Einstellungen enthält und auf dem Testsystem die anderen, oder oder oder ...))

                      echo "$verabschiedung $name";

                      1. Hi,

                        Man muss nur berücksichtigen, dass nicht jeder die Möglichkeit eingeräumt bekommt, die PHP-Konfiguration nach eigenem Gusto einzustellen.

                        Also was interne Konfigurationsmöglichkeiten zur Laufzeit angeht (http://php.net/manual/de/ref.errorfunc.php) herrscht doch kein Mangel.

                        Dazu käme dann noch http://php.net/set_error_handler.

                        error_reporting(0) am Anfang eines in der Produktivumgebung laufenden Scripts wäre auch noch eine Möglichkeit (wenn man nicht ständig vergessen würde, das bei jedem Upload anzupassen ... (Gut, man könnte sich auch mit dem Includen einer Datei behelfen, die die auf dem Produktivsystem gewünschten Einstellungen enthält und auf dem Testsystem die anderen, oder oder oder ...))

                        Yep. Ich include *immer* eine Basis-Bibliothek, die mir stetig nützliche Variablen (Überprüfung/Ergänzung z.B. des $_SERVER-Arrays), Konstanten (wie z.B. DEVELOPER) und Funktionen systemübergreifend zur Verfügung stellt. Die initialisiert auch mein System (z.B. eben mit der Feststellung, ob ich ein Developer bin ->localhost, nebst Fehlerbehandlung). Die Basis-Bibliothek sucht selbst nach einer kleinen Konfigurationsdatei. In dieser können spezififizierte Konstanten gesetzt, sowie eine beliebige Anzahl Developer und Content-Manager definiert werden. Z.B., kann der User "cybaer" dort eingetragen werden (was mich zum Developer macht, wenn ich mich online authentifiziert habe), oder alle User mit einer bestimmten IP, oder alle User mit einem bestimmten Namen von einer bestimmten IP ;-)). Wird keine Konfigurationsdatei gefunden, dann gelten halt nur die Defaults.

                        Insofern kann ich auch nicht vergessen, etwas nach dem Upload anzupassen.

                        Und ohne diese Basis-Bibliothek fange ich gar nicht erst an zu programmieren. Der entsprechende include ist bereits im Template für ein neues PHP-Script enthalten. ;)

                        Gruß, Cybaer

                        --
                        Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!