Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Rückgabewerte und wie auf Fehler reagieren

Einklappen

Neue Werbung 2019

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

  • [Erledigt] Rückgabewerte und wie auf Fehler reagieren

    Gibt es eigentlich eine allgemeine Regel was eine Methode zurück geben sollte?
    Vor allem will ich wissen wie man am besten auf Fehler reagiert.

    Es ist praktisch, wenn das aufrufende Script/Objekt/Controller mit einem

    if($meinObject->machwas($wert)) {
    // alles gut, mach weiter
    }else{
    // Hilfe schreien
    }

    reagiert. machwas() gibt also ein true oder false zurück.
    Mal angenommen machwas() macht mehrere Dinge und eins davon geht schief und es kommt ein false zurück. Dann will ich vielleicht wissen, was davon nicht geklappt hat. Mir fallen folgende Lösungsansätze ein.

    1.) Ich gebe statt einem false ein Array oder Objekt zurück. Dann müsste ich in der else Bedinnung prüfen was da zurückkommt.
    2.) Ich könnte der Klasse eine Eigenschaft geben wie „isTrue“ auf das ich dann prüfen kann und eine error Eigenschaft in dem ich den Fehler schreibe/abfrage.
    3.) Oft sehe ich auch, dass generell ein Array oder Objekt zurückgegeben wird. zB. Return array('isTrue’ => false, ’error’ => ’Datei nicht gefunden’ )

    Was ist elegant und was sollte man vermeiden?

    Dass man kritische Methoden mit try-catch abfangen sollte ist mir klar, nur weiß ich im catch Block auch nicht was den Fehler verursacht hat und wie darauf reagieren soll.

  • #2
    Dafür sind Exceptions dar. Du kannst für dann für den Entsprechenden Fehler eine Exception werden (für jede Fehlerart z.b. eine andere Exception). Und im try-catch-Block kannst du dann entsprechend die einzelnen Exceptions abfangen und darauf reagieren. Siehe auch im Manual.

    Kommentar


    • #3
      Hi airobix,

      wie Flor1an schon sagt sollte man für diese Art von Fehlerabfragen auf jeden Fall Exceptions verwenden. Folgendes hat sich bei uns in der Entwicklung als gutes Pattern bewährt:

      1. Möglichst fein granulare Funktionen (ca. 20 - 40 Zeilen Code und nicht mehr als eine wikliche Action)

      PHP-Code:
      function tuWas()
      {
        if(!
      checkFirst)
           throw new 
      FirstCheckException("First Fail");

        if(!
      checkSecond)
           throw new 
      SecondCheckException("Second Fail");

        
      //... 
        //tuWas
        //...

        
      return $result;

      2. FirstCheckException und SecondCheckException sind Ableitungen von Exception.

      3. An der Stelle wo die Funktion aufgerufen wird macht man dann folgendes:
      PHP-Code:
      // ...

      try{
        
      tuWas();
      }catch(
      FirstCheckException $e){
        
      // First Check ist gescheitert
      }catch(SecondCheckException $e){
         
      // Second Check ist gescheitert
      }catch (Exception $e) {
        
      // Irgendwas anderes ist gescheitert

      Gruß
      René
      [URL="http://penner.name"]mein blog[/URL]

      Kommentar


      • #4
        PHP: Ausnahmebehandlung - Manual
        "[URL="http://www.youtube.com/watch?v=yMAa_t9k2VA&feature=youtu.be&t=25s"]Mein Name ist Lohse, ich kaufe hier ein.[/URL]"

        Kommentar


        • #5
          @papst: Das Beispiel ist doch sehr allgemein gehalten und ist IMHO Nicht für alle Anwendungsfälle sinnvoll.
          [COLOR="#F5F5FF"]--[/COLOR]
          [COLOR="Gray"][SIZE="6"][FONT="Georgia"][B]^^ O.O[/B][/FONT] [/SIZE]
          „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
          [URL="http://www.php.de/javascript-ajax-und-mehr/107400-draggable-sorttable-setattribute.html#post788799"][B]Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“[/B][/URL][/COLOR]
          [COLOR="#F5F5FF"]
          --[/COLOR]

          Kommentar


          • #6
            Hi nikosch ...

            wie du siehst ist auch die Frage sehr allgemein, so dass die Antwort wohl passent ist

            Gibt es eigentlich eine allgemeine Regel was eine Methode zurück geben sollte?
            Gruß
            René
            [URL="http://penner.name"]mein blog[/URL]

            Kommentar


            • #7
              Nein eben nicht. Eine allgemeine Frage sollte keine spezielle Antwort erhalten.
              [COLOR="#F5F5FF"]--[/COLOR]
              [COLOR="Gray"][SIZE="6"][FONT="Georgia"][B]^^ O.O[/B][/FONT] [/SIZE]
              „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
              [URL="http://www.php.de/javascript-ajax-und-mehr/107400-draggable-sorttable-setattribute.html#post788799"][B]Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“[/B][/URL][/COLOR]
              [COLOR="#F5F5FF"]
              --[/COLOR]

              Kommentar


              • #8
                Florian gesagt hat, ist dafür wohl eine Exception am geeignetsten.
                Entweder du machst für jeden Fehler eine Excpetion und fragst dann auf diese Excpetion eben ab
                PHP-Code:
                class Invalid_Name_Exception extends Exception {} 
                oder was vielleicht einfacher wäre, du gehst auf den Message-Code, den du bei der Excpetion wirfst.

                Am besten wäre warscheinlich eine Kombination aus beidem.
                "My software never has bugs, it just develops random features."
                "Real programmers don't comment. If it was hard to write, it should be hard to understand!"

                Kommentar


                • #9
                  Vielen Dank. Auch wenn's allgemein war, hilft mir das schon mal weiter. Exceptions wurden von mir bisher nicht richtig eingesetzt, zumindest nicht mit mehreren Catch Anweisungen wie oben beschrieben. Danke, das werde ich sicherlich übernehmen (wenn es passt).

                  Wenn ich noch mal kurz auf den Rückgabewert zurückkommen darf. Mal abgesehen von dem Fehlerfall, gibt es da eine elegante Regel? Was sollte man zurückgeben? Ich grübel immer, ob ich die gewünschte Änderungen, die eine Methode hervorruft in ein/das Objekt speichern soll, oder ob es platt zurückgegeben werden soll.

                  Ein "allgemeine" Antwort würde mir reichen .

                  Kommentar


                  • #10
                    IMHO sollten Objekte immer den gleichen Typ zurückgeben.
                    D.h. wenn deine Funktion normalerweise ein Array von Daten zurückgibt, empfinde ich es für schlecht, wenn dieselbe Funktion im Fehlerfall false zurückliefert.
                    "My software never has bugs, it just develops random features."
                    "Real programmers don't comment. If it was hard to write, it should be hard to understand!"

                    Kommentar


                    • #11
                      Eine pauschale Antwort ist aber nunmal nicht für jeden Anwendungsfall sinnvoll.

                      Ich versuche auch in den meisten Objektmethoden die Funktionsweise atomar funktional zu gestalten - die Rückgabe repräsentiert die Funktion über die Eingaben. Im allgemeinen finde ich es sinnvoll, erst im aufrufenden Kontext die Member des Objekts zu schreiben. Damit ergibt sich für die aufgerufene Methode eine größere Anwendungsbreite.
                      [COLOR="#F5F5FF"]--[/COLOR]
                      [COLOR="Gray"][SIZE="6"][FONT="Georgia"][B]^^ O.O[/B][/FONT] [/SIZE]
                      „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                      [URL="http://www.php.de/javascript-ajax-und-mehr/107400-draggable-sorttable-setattribute.html#post788799"][B]Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“[/B][/URL][/COLOR]
                      [COLOR="#F5F5FF"]
                      --[/COLOR]

                      Kommentar


                      • #12
                        Haste natürlich auch recht.
                        "My software never has bugs, it just develops random features."
                        "Real programmers don't comment. If it was hard to write, it should be hard to understand!"

                        Kommentar


                        • #13
                          @Nikosch: Hmmm ... ich verstehe leider Deine Antwort nicht ganz.
                          die Rückgabe repräsentiert die Funktion über die Eingaben
                          Was meinst Du damit?
                          Im allgemeinen finde ich es sinnvoll, erst im aufrufenden Kontext die Member des Objekts zu schreiben.
                          Meinst Du, dass Du das Objekt mit den nötigen Daten erst im aufrufendem Kontext befüllst?

                          Z.B.
                          PHP-Code:
                          $person1 = new Person();
                          $person1->addName('Lieschen Müller'); 
                          ???

                          Kommentar


                          • #14
                            Dein Beispiel belegt gut meine Aussage:
                            Eine pauschale Antwort ist aber nunmal nicht für jeden Anwendungsfall sinnvoll.
                            Natürlich muss eine Setter Methode direkt ins Objekt schreiben. Genau wie eine Getter-Methode immer direkt daraus lesen wird und auch deren Rückgabe festgelegt ist. Für alle anderen Methoden ist die Frage aber nicht pauschal zu beantworten.

                            die Rückgabe repräsentiert die Funktion über die Eingaben
                            Code:
                            Rückgabe = Funktion (Eingabe, Eingabe);
                            Das ist das Prinzip einer Funktion. In einem Objekt kann das schnell aufweichen, weil es einen zusätzlichen „objektglobalen“ Kontext gibt, in den man die Rückgabe direkt schreiben kann. Wo das möglich ist, rate ich dazu, das zu vermeiden und dies statt dessen ander Stelle zu tun, wo $this->myMethod ($in1, ..); aufgrufen wird.
                            [COLOR="#F5F5FF"]--[/COLOR]
                            [COLOR="Gray"][SIZE="6"][FONT="Georgia"][B]^^ O.O[/B][/FONT] [/SIZE]
                            „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                            [URL="http://www.php.de/javascript-ajax-und-mehr/107400-draggable-sorttable-setattribute.html#post788799"][B]Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“[/B][/URL][/COLOR]
                            [COLOR="#F5F5FF"]
                            --[/COLOR]

                            Kommentar


                            • #15
                              Hmmm ... ich bin noch nicht ganz erleuchtet. Folgendes konstruiertes Beispiel. Ich habe eine Klasse Person, instanziere mir zwei Objekte und lasse sie einander heiraten. Jetzt kann die Aktion schief gehen, weil eine Person bereits verheiratet oder Minderjährig ist. Die Methode "marriageAllowed($person1, $person2)" ist der einfachheit her eine Methode der Person und prüft ob eine heirat möglich ist. Diese prüft auf Alter und bereits verheiratet. Jetzt würde sich bei mir die Frage der Rückgabe stellen.

                              Wenn ich mir jetzt Eure Antworten durchlese, müsste ich am elegantesten ich die Methode "marriageAllowed()" atomarisieren in zwei Methoden "isOldEnoughToMarry($date)" und "isMarried($person)" die jeweils true/false zurückgeben. In der Methode marriageAllowed()
                              versuch ich die beiden Funktionen nacheinander mit zu prüfen und im Fehlerfall schmeiße ich eine Exception, oder?

                              etwa so (sehr vereinfacht ) :

                              PHP-Code:
                              class Person(){

                              var 
                              $name;
                              var 
                              $partner null;
                              var 
                              $dateOfBirth null;


                              function 
                              setName($name){
                                  
                              $this->name $name;
                              }
                              function 
                              marriageAllowed(Person $person1Person $person2){

                                       if(
                              $person1->isOldEnoughToMarry($person1->dateOfBirth === false) {
                                           throw new 
                              Exception("Person ".$person1->getName." nicht alt genug"); 
                                       }

                                       if(
                              $person2->isOldEnoughToMarry($person2->dateOfBirth === false) {
                                           throw new 
                              Exception("Person ".$person2->getName." nicht alt genug"); 
                                       }
                                       if(
                              $person1->isMarried() !== false) {
                                           throw new 
                              Exception("Person ".$person1->getName." ist bereits verheiratet "); 
                                       }

                                       if(
                              $person2->isMarried() !== false) {
                                           throw new 
                              Exception("Person ".$person2->getName." ist bereits verheiratet "); 
                                       }
                                      
                              retrun true;
                              }

                              function 
                              isOldEnoughToMarry($date) {

                                if(
                              $date heute vor 18 Jahren) {
                                   return 
                              true;
                                }else{
                                   
                              retrun false
                                 
                              }
                              }

                              function 
                              isMarried(Preson $person) {

                                 if(
                              $person->partner === null) {
                                    return 
                              true;
                                 }else{
                                    return 
                              false;
                                 }
                              }

                              }

                              $person1 = new Person();
                              $person1->setName('Liesschen')
                              $person2 = new Person();
                              $person2->setName('Peter')

                              try{
                                
                              Person::marriageAllowed($person1,$person2)
                              } catch (
                              Exception $e) { 
                                echo 
                              $e->getMessage(); 

                              Kommentar

                              Lädt...
                              X