Ankündigung

Einklappen
Keine Ankündigung bisher.

Fehler korrekt fangen

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Fehler korrekt fangen

    Tach auch.

    Ich versuche einen Fehler beim Verschieben eines Verzeichnisses zu fangen.
    Leider kenne ich mit den Fehlerfunktionen von PHP noch nicht so aus.

    Folgendes gibt mir erst einen "Unknown error type" und dann eine "WARNING" aus:
    PHP-Code:
    //error handler function
    function myErrorHandler($errno$errstr$errfile$errline)
    {
        switch (
    $errno) {
        case 
    E_USER_ERROR:
            echo 
    "<b>ERROR</b> [$errno$errstr<br />\n";
            echo 
    "  Fatal error on line $errline in file $errfile";
            exit(
    1);
            break;

        case 
    E_USER_WARNING:
            echo 
    "<b>WARNING</b> [$errno$errstr<br />\n";
            break;

        case 
    E_USER_NOTICE:
            echo 
    "<b>NOTICE</b> [$errno$errstr<br />\n";
            break;

        default:
            echo 
    "Unknown error type: [$errno$errstr<br />\n";
            break;
        }

        
    /* Do not execute PHP internal error handler */
        
    return true;
    }

    $old_error_handler set_error_handler("myErrorHandler");

    if(!
    rename("abc""xyz"))
    {
        
    trigger_error('Could not rename directory'E_USER_WARNING);

    PHP-Code:
    //Ausgabe:
    Unknown error type: [2rename(abc,xyz) [function.rename]: No such file or directory
    WARNING 
    [512Could not rename directory
    Wie verhindere ich, dass "default" im switch angesprungen wird? Ich will nur die Warnung ausgeben.


  • #2
    Es handelt sich hier um Flags, Bitpositionen an einer bestimmten Stelle in einem DWORD. Diese Information kommt nicht zwangsläufig "standalone", sondern u.U. mit anderen Flags in Kombination.

    Um ein Flag abzufragen, muss man es ausmaskieren:
    PHP-Code:
    if ($errno E_USER_ERROR == E_USER_ERROR) { 
      
    // Es ist ein E_USER_ERROR
    }
    elseif (
    $errno E_USER_WARNING == E_USER_WARNING) {
      
    // Es ist eine E_USER_WARNING

    Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

    Kommentar


    • #3
      Verstehe ich nicht.

      Die Error-Level-Konstanten sind Integer.
      Du erzeugst mit deinem Code doch
      if($errno & true)
      Ausserdem habe ich das gerade ausprobiert und ich bekomme immer noch zwei Meldungen.

      Irgendwie muss ich verhindern, dass eine Fehlermeldung bereits bei der Rename-Funktion erzeugt wird...
      Ein "@rename()" funkioniert nicht.

      Kommentar


      • #4
        Zitat von chunky Beitrag anzeigen
        Verstehe ich nicht.

        Du erzeugst mit deinem Code doch
        if($errno & true)
        Ausserdem habe ich das gerade ausprobiert und ich bekomme immer noch zwei Meldungen.

        Irgendwie muss ich verhindern, dass eine Fehlermeldung bereits bei der Rename-Funktion erzeugt wird...
        Ein "@rename()" funkioniert nicht.
        Ich kann dir nicht ganz folgen.

        Zunächst einmal: $errno kann einen Wert enthalten, der mehrere Informationen transportiert. Man nennt so etwas ein Bitfeld, die einzelnen Bits werden Flag genannt. Beispiel: Du schaltest dein Error-reporting an:
        PHP-Code:
        error_reporting (E_ERROR E_STRICT); 
        Hier setzt du die Flags E_ERROR (nummerischer Wert 1 oder 2^0 - Bit 0) und E_STRICT (nummerischer Wert 1024 oder 2^10 - Bit 10), die per Bit-OR miteinander verknüpft werden.
        Code:
          0000 0000 0000 0001 (1)
        | 0000 0010 0000 0000 (1024)
        ----------------------------
          0000 0010 0000 0001 (1025)
        Das Ergebnis dieser Operation ist 1025. Würdest du nun einen direkten Vergleich durchführen, ob z.B. E_STRICT gesetzt ist, kannst du das nicht so machen:
        PHP-Code:
        if ($errno == E_STRICT// evaluiert zu 1025 == 1024 
        Dieser Vergleich schlägt fehl! Du musst das entsprechende Bit vorher ausmaskieren, um es Abfragen zu können:
        Code:
          0000 0010 0000 0001 (1025)
        & 0000 0010 0000 0000 (1024)
        ----------------------------
          0000 0010 0000 0000 (1024)
        $errno & true ist jedenfalls nicht das gleiche.

        Und rename() benennt Dateien um:
        PHP-Code:
        rename("abc""xyz"
        Hast du eine Datei namens abc die du umbenennen willst?


        Edit:Kann sein, das du zum Teil Recht hattest.. eventuell muss man beim maskieren Klammern setzen:
        PHP-Code:
        if ( ($errno E_USER_ERROR) == E_USER_ERROR
        Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

        Kommentar


        • #5
          Zitat von lstegelitz Beitrag anzeigen
          Kann sein, das du zum Teil Recht hattest.. eventuell muss man beim maskieren Klammern setzen:
          PHP-Code:
          if ( ($errno E_USER_ERROR) == E_USER_ERROR
          Nein, == steht höher in der Operatoren-Rangfolge als &.
          http://www.php.net/manual/en/languag...precedence.php


          Aber ganz abgesehen davon ...
          Es handelt sich hier um Flags, Bitpositionen an einer bestimmten Stelle in einem DWORD. Diese Information kommt nicht zwangsläufig "standalone", sondern u.U. mit anderen Flags in Kombination.
          Ersteres ist zwar richtig, allerdings habe ich bzgl. der möglichen „Kombination“ hier Zweifel.

          Ein Fehler kann doch nicht gleichzeitig bspw. E_ERROR und E_WARNING sein, die schliessen sich doch gegenseitig aus?
          Das Beispiel zu set_error_handler im Manual fragt auch nur direkt auf die Konstanten ab, ohne irgendwelche Bitoperationen.


          @chunky:
          Bei der zu engen Orientierung am Beispiel liegt hier aber auch der Fehler:
          E_USER_ERROR, E_USER_WARNING und E_USER_NOTICE werden abgefragt - der Fehler, der beim rename auftritt, ist aber nicht vom Typ E_USER_irgendwas.

          Alle E_USER-Konstanten sind für Fehler gedacht, die man im Script selber mittels trigger_error auslöst.

          Das fehlgeschlagene rename löst aber ein E_WARNING aus, also willst du das in deinem switch abfangen.

          Kommentar


          • #6
            Hmm, okay. Vielen Dank für den Hinweis und die Erläuterung.

            Meine Test-Datei sieht jetzt so aus:
            PHP-Code:
            <?php

            function myErrorHandler($errno$errstr$errfile$errline)
            {
                if ( (
            $errno E_USER_ERROR) == E_USER_ERROR)
                {
                    echo 
            "<b>ERROR</b>: $errstr<br />\n"//[$errno]
                    
            echo "  Fatal error on line $errline in file $errfile";
                    die();
                }
                elseif ( (
            $errno E_USER_WARNING) == E_USER_WARNING)
                {
                    echo 
            "<b>WARNING</b>: $errstr<br />\n"//[$errno]
                
            }
                elseif ( (
            $errno E_USER_NOTICE) == E_USER_NOTICE)
                {
                    echo 
            "<b>NOTICE</b>: $errstr<br />\n"//[$errno]
                
            }
                else
                {
                    echo 
            "Unknown error type: $errstr<br />\n"//[$errno]
                
            }

                
            /* Do not execute PHP internal error handler */
                
            return true;
            }
            $old_error_handler set_error_handler("myErrorHandler");

            rename("abc""xyz") or trigger_error('Could not rename directory'E_USER_WARNING);
            ?>
            Ausgabe:
            PHP-Code:
            Unknown error typerename(abc,xyz) [function.rename]: No such file or directory
            WARNING
            Could not rename directory 
            Wie man sieht werden trotzdem zwei Fehlermeldungen ausgegeben.

            Kommentar


            • #7
              Zitat von chunky Beitrag anzeigen
              Hmm, okay. Vielen Dank für den Hinweis und die Erläuterung.
              Allzu viel verstanden zu haben scheinst du davon aber nicht ...


              Wie man sieht werden trotzdem zwei Fehlermeldungen ausgegeben.
              Natürlich.

              rename schmeisst immer noch seine eigene Meldung, die ist vom Typ E_WARNING - den dein Errorhandler aber nicht (er)kennt, also kann der nur in den Default-Zweig gehen und „Unknown error type” ausgeben.

              Und dann anschliessend kommst du und schmeisst mit trigger_error noch mal eine eigene Meldung hinterher. Die ist jetzt vom Typ E_USER_WARNING, die erkennt dein Handler, also macht der da seine eigene Ausgabe, „WARNING” gefolgt von $errstr.

              Kommentar


              • #8
                Aha, okay. Und wie kann ich rename jetzt dazu bringen, keine Fehlermeldung zu werfen?
                Oder wenigstens meinen eigenen Fehlertext zu benutzen?

                Kommentar


                • #9
                  Zitat von chunky Beitrag anzeigen
                  Aha, okay. Und wie kann ich rename jetzt dazu bringen, keine Fehlermeldung zu werfen?
                  Oder wenigstens meinen eigenen Fehlertext zu benutzen?
                  In dem du endlich mal dein Hirn anschaltest, und die Hinweise, die du bekommen hast, auch umsetzt ...

                  rename wirft eine Meldung vom Typ E_WARNING - also ist dieser Typ auch das, worauf du in deinem eigenen error-handler reagieren willst.

                  Kommentar


                  • #10
                    Der Umgangston hier auf dem Forum überrascht mich immer aufs neue.

                    Ich will dem Error-Handler meine eigene Fehlermeldung übergeben. Sonst bräuchte ich das ganze nicht zu machen.

                    Kommentar


                    • #11
                      Zitat von chunky Beitrag anzeigen
                      Der Umgangston hier auf dem Forum überrascht mich immer aufs neue.
                      Und mich überrascht immer wieder auf's neue, wieso Leute programmieren, denen es so sehr an Fähigkeit mangelt, eigentlich vollkommen klar erklärte Sachverhalte zu verstehen.

                      Ich will dem Error-Handler meine eigene Fehlermeldung übergeben.
                      Ja dann mach's doch - niemand hält dich auf.

                      Alles, was du dazu wissen musst, steht im Handbuch erklärt.
                      Und auf die Stellen, an denen du das, was im Handbuch steht, offenbar nicht verstanden hast, bist du inzwischen mehrfach hingewiesen worden.

                      Kommentar


                      • #12
                        Zitat von ChrisB Beitrag anzeigen
                        Ein Fehler kann doch nicht gleichzeitig bspw. E_ERROR und E_WARNING sein, die schliessen sich doch gegenseitig aus?
                        Das Beispiel zu set_error_handler im Manual fragt auch nur direkt auf die Konstanten ab, ohne irgendwelche Bitoperationen.
                        Stimmt, das macht keinen Sinn (E_NOTICE und E_DEPRECATED hingegen schon, allerdings scheint E_DEPRECATED automatisch eine Notice zu sein). Technisch möglich wäre es trotzdem.

                        Ich gehe da lieber auf Nummer sicher - die Doku spricht von einem Bitfeld (zumindest beim Setzen des Reportinglevels) und als solches behandle ich das, damit stehe ich auf der sicheren Seite, falls irgendein Modul mal einen "zusammengesetzten" Fehlercode verwenden sollte (bin gebranntes Kind: so einen "Fehler" hab ich während der Ausbildung mal gehabt, da hab ich mir das explizite Maskieren angewöhnt)
                        Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

                        Kommentar


                        • #13
                          Ein switch/case wie im Eingangspost vom TE geschrieben reicht für die Fehlerbehandlung vollkommen aus, sein Ansatz war richtig.

                          Nutzt man if und will wissen ob ein Flag(Fehler Konstante) gesetzt ist, reicht in diesem Fall ein einfaches

                          PHP-Code:
                          if ($errno E_USER_ERROR)... 
                          statt

                          PHP-Code:
                          if ( ($errno E_USER_ERROR) == E_USER_ERROR)... 
                          DevBlog|3D Online-Shopping|Xatrium

                          Kommentar

                          Lädt...
                          X