[PHP]Gebruik van return, error of exception?

Pagina: 1
Acties:
  • 315 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Nu ik een tijdje met php bezig ben, me sinds kort meer op php richt en ook echt functionele tools aan het ontwikkelen ben vraag ik me wat af. Wat is de meest nette manier om "iets wat niet lukt" af te handelen?

In principe kan je (net als algemene php functies dat doen) een return waarde geven. Je kan ook als iets niet lukt een error triggeren, en tot slot kan je een uitzondering opgooien. Maar wat is nu eigenlijk de meest nette oplossing?

Ter illustratie even drie voorbeelden op een rij, allemaal om deze casus heen:
PHP:
1
2
3
4
5
6
7
class foo{
  public static function bar(){
    if( $this->will_this_work() )
      return do_something();
  }
}
$test = foo::bar();
Als het nu niet zal werken (will_this_work is false), kan je het op de drie manieren oplossen:

Return
PHP:
1
2
3
4
5
6
7
8
9
10
class foo{
  public static function bar(){
    if( $this->will_this_work() )
      return do_something();
    else
      return false;
  }
}
if( $test = foo::bar() )
  print "er ging iets mis";

Error
PHP:
1
2
3
4
5
6
7
8
9
class foo{
  public static function bar(){
    if( $this->will_this_work() )
      return do_something();
    else
      trigger_error( "Er ging iets mis" , E_USER_WARNING );
  }
}
$test = foo::bar();

Exception
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
class foo{
  public static function bar(){
    if( $this->will_this_work() )
      return do_something();
    else
      throw new Exception( "Er ging iets mis" );
  }
}
try{
  $test = foo::bar();
}catch( Exception $e ){
  echo $e->getMessage();
}
Ik gebruikte vroeger veel de eerste (php4), en ben nu af en toe een error aan het triggeren, soms een exception, soms retourneer ik onwaar. Maar ik zit nu wel in dubio: wat is nu het beste?

Ik verwacht dat iedereen die exceptions het "beste" vind. Maar waarom bestaan die andere manieren dan? Gebeurt het überhaupt wel eens dat je een error triggert? Ik snap niet goed in welk geval je trigger_error gebruikt en wanneer je een uitzondering opgooit :s

Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 18-09 16:28

Bosmonster

*zucht*

Exceptions hebben ook zo hun voor- en tegenstanders.

Ik denk dat het belangrijker is dat je je methode consequent doorvoert.

Acties:
  • 0 Henk 'm!

  • ChessSpider
  • Registratie: Mei 2006
  • Laatst online: 01-08 19:01
Dat ligt toch juist heel erg veel aan wat voor uitzondering het is?
Als je wilt checken of iemand ingelogd is, ga je geen exception throwen en dan kijken of er een exception is gegooid, maar ga je gewoon false returnen.

Als je veel met classes en etc werkt zijn exceptions mooier dan error triggering, maar hetgene wat ik voor fouten vaak gebruikt is gewoon error triggering en dan met een set_error_handler de foutmeldingen loggen naar een bestand toe.

Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 18-09 16:28

Bosmonster

*zucht*

ChessSpider schreef op vrijdag 18 januari 2008 @ 10:55:
Dat ligt toch juist heel erg veel aan wat voor uitzondering het is?
Als je wilt checken of iemand ingelogd is, ga je geen exception throwen en dan kijken of er een exception is gegooid, maar ga je gewoon false returnen.
Iemand die verkeerd inlogt wil ik ook geen 'error' noemen. En kijken of iemand ingelogd is heeft al helemaal niks met error-handling te maken natuurlijk. Je vraagt om een state en krijgt true/false terug.

[ Voor 15% gewijzigd door Bosmonster op 18-01-2008 11:47 ]


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Uiteraard snap ik dat het controleren van in of uitgelogd zijn een true of false moet retourneren :)
Bosmonster schreef op vrijdag 18 januari 2008 @ 11:46:
[...]
Iemand die verkeerd inlogt wil ik ook geen 'error' noemen. En kijken of iemand ingelogd is heeft al helemaal niks met error-handling te maken natuurlijk. Je vraagt om een state en krijgt true/false terug.
Wat zou er dan teruggekoppeld moeten worden bij een $user->login(); ? Ik zou niet zeggen dat je iemand "probeert" in te loggen, en als dat niet lukt je er een uitzondering tegenaan gooit. Verkeerde naam of wachtwoord: error! Het is niet gelukt om je in te loggen! Of bekijk ik dat nu gewoon verkeerd?

Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 18-09 16:28

Bosmonster

*zucht*

mithras schreef op vrijdag 18 januari 2008 @ 11:53:
Uiteraard snap ik dat het controleren van in of uitgelogd zijn een true of false moet retourneren :)

[...]
Wat zou er dan teruggekoppeld moeten worden bij een $user->login(); ? Ik zou niet zeggen dat je iemand "probeert" in te loggen, en als dat niet lukt je er een uitzondering tegenaan gooit. Verkeerde naam of wachtwoord: error! Het is niet gelukt om je in te loggen! Of bekijk ik dat nu gewoon verkeerd?
Het is maar hoe je ertegenaan kijkt inderdaad. OO-gezien zou je goed met exceptions kunnen werken, ook bij inloggen. Dan kun je ook heel wat precieser te werk gaan dan alleen true/false (zonder heel ingewikkeld/ondoorzichtig te moeten gaan doen.

Maar imho hangt de methode voornamelijk af van hoe je programmeert. Als je functioneel programmeert met PHP4 bijvoorbeeld, dan zou ik niet ineens exceptions gaan gebruiken.

Als je volledig OO programmeert in PHP5, dan passen exceptions daar natuurlijk een stuk beter in.

Zolang je maar consequent bent.

Acties:
  • 0 Henk 'm!

  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 20:40

Reptile209

- gers -

Misschien ga ik te veel op je voorbeeld in, maar een functie met de naam will_this_work schreeuwt om een boolean result. Dat gebruik je dus typisch voor een vlag-functie, waarbij je weet en verwacht dat iets aan of uit, true of false is.
Stel dat je van een (ingelogde) user gegevens wil ophalen met een functie get_userdata. Dan is een errorcode nuttig om aan te geven dat er iets mis is met de data (die is bijvoorbeeld nooit ingevuld), of direct een error meegeven ("je hebt geen rechten om [data] te bekijken!"). Een exceptie zou ik bewaren voor het vreemde, maar niet onmogelijke, geval dat de user opeens helemaal niet ingelogd blijkt te zijn. Dat is namelijk exceptioneel gedrag dat je niet bij iedere functie wil gaan checken, maar waarvan je een bepaalde status aanneemt. Als die status opeens niet blijkt te kloppen, moet je code grote stappen gaan maken naar het corrigeren van het probleem (user redirecten naar een inlogscherm bijvoorbeeld).
Er is dus in mijn beleving niet één goed antwoord op je vraag: het is context afhankelijk.

Zo scherp als een voetbal!


Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 09:34
Reptile209 schreef op vrijdag 18 januari 2008 @ 21:17:
Er is dus in mijn beleving niet één goed antwoord op je vraag: het is context afhankelijk.
Hier sluit ik me bij aan :)

Het hangt ook een beetje af hoe je met excepties omgaat trouwens; meestal hanteer ik de instelling dat als informatie opvragen fout gaat je een false terugkrijgt en wanneer je een actie probeert uit te voeren die mislukt een exception gethrowed wordt. Ergo, $user -> loggedIn() zal doorgaans true of false retourneren terwijl $backoffice -> deleteUser(); een backofficeException zal throwen als bijvoorbeeld de user niet bestaat.

Uiteindelijk gooi ik vaak in m'n pagehandler bovendien nog een try/catch om m'n model heen die alle Exceptions afvangt (met een speciale error pagina) en wil ik 'kleine' excepties nog wel eens binnen een class afvangen die vervolgens een error op de pagina set (maar de pagina zal verder wel gewoon te zien zijn).

trigger_error gebruik ik dan weer nooit trouwens, maargoed, code ook alleen maar OO in PHP5 :)

[ Voor 5% gewijzigd door FragFrog op 18-01-2008 23:26 ]

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • Sh4wn
  • Registratie: December 2006
  • Laatst online: 12-11-2017

Sh4wn

Bio-informatica

Ik gebruik exceptions meer voor fouten van de programmeur die bijv. mijn class gebruikt. Verder gebruik ik nooit trigger_error in mijn class, dat is zooo PHP4 :')

Voor de rest ga ik 100% met Retpile mee

[ Voor 11% gewijzigd door Sh4wn op 19-01-2008 00:23 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Bosmonster schreef op vrijdag 18 januari 2008 @ 11:57:
[...]


Het is maar hoe je ertegenaan kijkt inderdaad. OO-gezien zou je goed met exceptions kunnen werken, ook bij inloggen. Dan kun je ook heel wat precieser te werk gaan dan alleen true/false (zonder heel ingewikkeld/ondoorzichtig te moeten gaan doen.

Maar imho hangt de methode voornamelijk af van hoe je programmeert. Als je functioneel programmeert met PHP4 bijvoorbeeld, dan zou ik niet ineens exceptions gaan gebruiken.

Als je volledig OO programmeert in PHP5, dan passen exceptions daar natuurlijk een stuk beter in.

Zolang je maar consequent bent.
Exceptions zijn voor onverwachtte fouten in het afhandelen van code...het niet/verkeerd opgeven van een wachtwoord waardoor deze niet overeenkomt met het wachtwoord in de database is geen exception...dat is een van de verwachtte mogenlijkheden van je functie (login).

Acties:
  • 0 Henk 'm!

  • kokx
  • Registratie: Augustus 2006
  • Laatst online: 13-09 20:30

kokx

WIN

Ik denk dat een aantal mensen hier Exceptions echt behandelen zoals ze genoemd zijn. Maar Exceptions zijn niet zomaar errors of uitzonderingen. Het grote voordeel aan Exceptions is dat ze opgevangen kunnen worden, en dus eigenlijk voor elke non-fatal error gebruikt kunnen worden. Beter gezegd, alles wat er niet voor zorgt dat je applicatie niet normaal door kan draaien, daar zou je een Exception voor kunnen gooien. En op plaatsen waar je soms Exceptions verwacht kun je ze voor van alles gebruiken. Voor het checken van een login zou je een Exception kunnen gooien en deze een level lager weer opvangen, als de gebruiker niet ingelogd is, al is in zo'n geval het retourneren van true/false beter (behalve als er een geval is welke niet standaard voor zou moeten komen).

Trigger_error vind ik op dit moment als functie niet echt nuttig, behalve als je aan een framework werkt, om anderen te waarschuwen dat ze verkeerde input geven (als zou ik, als je daar ook PHP5 OOP gebruikt, ook Exceptions gebruiken, zodat een gebruiker dit kan opvangen). Het grote probleem aan trigger_error is dat het niet opgevangen kan worden. Dus voor iets als inloggen e.d. heb je het niet nodig.

Het gewoon retourneren van true/false is natuurlijk ook een mogelijkheid (en dan vooral voor het checken of iemand ingelogd is).

Net als de meesten hiervoor, vind ik ook dat het aan de context ligt (wil je meer iets checken, of wil je iets aangeven dat niet klopt). Ik zelf moedig vooral het gebruik van Exceptions aan, maar wel op de goede plaats, en niet om te checken of iemand ingelogd is. Maar je kunt dit bijvoorbeeld wel doen bij het inloggen, om te retourneren dat het wachtwoord of gebruikersnaam niet klopt, en er van uit gaan dat als er geen Exception gegooid is, dat de gebruiker ingelogd is.

Acties:
  • 0 Henk 'm!

  • ChessSpider
  • Registratie: Mei 2006
  • Laatst online: 01-08 19:01
kokx schreef op zaterdag 19 januari 2008 @ 11:27:
(...) kan opvangen). Het grote probleem aan trigger_error is dat het niet opgevangen kan worden. Dus voor iets als inloggen e.d. heb je (..)
http://nl2.php.net/manual/en/function.set-error-handler.php ?

Ik gebruik vooralsnog alleen trigger_error, omda'k nog niet echt heb gekeken naar het throwen van exceptions...Ikzelf vind het vooralsnog goed werken, ookal is dat misschien uit onwetendheid..

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

(jarig!)
ChessSpider schreef op zaterdag 19 januari 2008 @ 11:29:
http://nl2.php.net/manual/en/function.set-error-handler.php ?

Ik gebruik vooralsnog alleen trigger_error, omda'k nog niet echt heb gekeken naar het throwen van exceptions...Ikzelf vind het vooralsnog goed werken, ookal is dat misschien uit onwetendheid..
Je kan het alsnog niet (handig) in dezelfde context opvangen waar je een bepaalde functiecall deed. Met een exception of een speciale return-var is dat een heel stuk makkelijker. En met exceptions heb je dan zelfs de vrijheid om het op een willekeurig hoger niveau te doen ipv direct bij de falende functiecall.

Trigger error is soms wel nuttig als debug-functie op het moment dat je een notice opgooit, dat is dan weer iets dat je niet met exceptions en return-vars kan doen. Maar anderzijds kan je bijna net zo makkelijk een echo ergens in je code zetten als je geen zin hebt geavanceerdere debugging te gebruiken.

Acties:
  • 0 Henk 'm!

  • YopY
  • Registratie: September 2003
  • Laatst online: 13-07 01:14
Het grote voordeel aan Exceptions is dat ze opgevangen kunnen worden, en dus eigenlijk voor elke non-fatal error gebruikt kunnen worden. Beter gezegd, alles wat er niet voor zorgt dat je applicatie niet normaal door kan draaien, daar zou je een Exception voor kunnen gooien.
Daar ben ik het niet mee eens. Een exception is meer dan een manier om na te gaan of er iets fout ging, het geeft ook informatie over wat er mis ging (mits goed gebruikt). Dus wanneer je een query uitvoert op de database (oid) en die mislukt omdat je database niet bestaat (oid), geeft je databaselaag netjes een Exception terug. Het aanroepende gedeelte van je webapp geeft vervolgens de informatie die daarin opgeslagen staat terug aan de gebruiker en / of schrijft het weg in een logbestand, zodat je na kunt gaan wat er mis ging, waar het mis ging, enzovoorts.

Het gebruiken van exceptions bij het mislukken van een login vindt ik ook niet logisch. Immers, als een login niet lukt is het toch geen onverwachte situatie, en ligt het probleem hem niet in het programma?

Simpel gesteld is het beter om een login functie aan te roepen die false teruggeeft als het niet lukt. Beetje geavanceerder voeg je een isLoggedIn() functie toe aan bijvoorbeeld je user klasse, of een loginSuccessful() als je een specifieke login klasse hebt. Je moet gewoon iets hebben waaraan je kunt vragen of de login gelukt is.

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Tja, ik zou dus geen exception opgooien als je een user wil inloggen. Eerder zou ik gaan voor een dergelijke constructie als volgend voorbeeld. Het gaat in dit geval om een database-actie, waar je wellicht een uitzondering op je actie (sessie toevoegen) verwacht. Het mislukken van inloggen is echter geen uitzondering, maar een fout (dus error). Dit kan je afvangen, en tegelijkertijd een boolean terugkoppelen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// other $user-> things
$user->login();

class user{
  // other functions and properties

  /**
   * @return bool
   */
  function login(){
    try{
      $session = new Session();
      $session->user_id = $this->id;
      $session->save();
    }catch( Exception $e){
      trigger_error( $e->getMessage(), E_USER_WARNING );
    }
    return $this->inGroup( 'users' );
  }
}
Misschien behoeft het wat uitleg, want ik vang alle errors af met een eigen handler en laat het bericht zien aan de gebruiker. Zo kan je een E_USER_WARNING triggeren als een user failed bij inloggen en een notice wanneer een visitor het contactformulier leeg laat :)
Sh4wn schreef op zaterdag 19 januari 2008 @ 00:22:
Ik gebruik exceptions meer voor fouten van de programmeur die bijv. mijn class gebruikt. Verder gebruik ik nooit trigger_error in mijn class, dat is zooo PHP4 :')
En daarom snap ik jouw reactie ook niet: trigger_error is een prima methode om inclusief een error handler een goede applicatie te schrijven (php5 of php4).

Wat maakt volgens jou een exception zoveel superieur aan een error, en waarom is het verkeerd om een error te triggeren?

[ Voor 9% gewijzigd door mithras op 19-01-2008 18:27 ]


Acties:
  • 0 Henk 'm!

  • AtleX
  • Registratie: Maart 2003
  • Niet online

AtleX

Tyrannosaurus Lex 🦖

Een Exception is af te vangen met een try{}-catch() block, en dus kan de uiteindelijke gebruiker (=programmeur) van een stuk code bepalen hoe fouten afgehandeld moeten worden. Een error die getriggerd wordt met behulp van trigger_error() is alleen op te vangen met een custom error handler.

In jouw voorbeeld convert je een exception naar een error puur voor opmaak doeleinden. Tenminste, zo leg je het uit. Waarom maak je niet gewoon een custom LoginFailedException als je toch zo graag een error wilt throwen? Imho moet dat in dit geval ook niet. Exceptions dienen voor onverwachte zaken, en daarom zijn ze programmeer-technisch ook duur. Exceptions throwen kost namelijk veel tijd, tijd die je zeker in een web-omgeving wel beter kunt gebruiken. Omdat Login() eigenlijk een method is die een boolean result heeft (het lukt, ja of nee) zou ik in dit geval gewoon een boolean returnen.

Zie ook Wikipedia - Exception handling voor meer informatie.

[ Voor 7% gewijzigd door AtleX op 19-01-2008 18:35 ]

Sole survivor of the Chicxulub asteroid impact.


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
mithras schreef op zaterdag 19 januari 2008 @ 18:25:
En daarom snap ik jouw reactie ook niet: trigger_error is een prima methode om inclusief een error handler een goede applicatie te schrijven (php5 of php4).

Wat maakt volgens jou een exception zoveel superieur aan een error, en waarom is het verkeerd om een error te triggeren?
Exceptions zin meer OO, je kan netjes een hele hierarchie maken en het verwerken middels catch in de aanroepende context is veel netter dan een custom error handler, wat ACM reeds verteld heeft.

En nog een mooie quote over dit onderwerp (quote linkt naar niet voor iedereen toegankelijk forum)
curry684 schreef op zondag 23 december 2007 @ 14:11:
...Inheritance van exceptions is evenzeer nuttig om specifiek op bepaalde niveaus af te kunnen handelen, of specifieke foutmeldingen te kunnen geven. Je zou bijvoorbeeld van Exception zelf de volgende exceptions kunnen afleiden:
code:
1
2
3
4
5
6
7
8
9
Exception
+- IOException
  +- FileException
    +- FileNotFoundException
    +- VolumeFullException
    +- ...
  +- NetworkException
    +- HostNotFoundException
etc. etc.

...
Voor een gedetailleerdere uitleg kun je hier eens kijken. Gewoon negeren dat het over Java gaat, exceptions zijn in iedere taal essentieel hetzelfde :)

{signature}


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Voutloos schreef op zaterdag 19 januari 2008 @ 20:06:
[...]
Exceptions zin meer OO, je kan netjes een hele hierarchie maken en het verwerken middels catch in de aanroepende context is veel netter dan een custom error handler, wat ACM reeds verteld heeft.
Mm, op zich is dat inderdaad wel begrijpelijk, en in die zin netter dan een error. Dus eigenlijk juist ook omdat je het afvangen van uitzonderingen aan een laag hoger aflaat. De laag zelf mag in die zin geen beslissing nemen of de uitgevoerde taak ongunstig is (wat met een error wel zo is, de laag zelf zal de error triggeren).
En nog een mooie quote over dit onderwerp (quote linkt naar niet voor iedereen toegankelijk forum)
[...]
Ik wist dat ik het ergens eerder gelezen had, maar niet waar :p Ja klopt, dus in principe kan je zeggen dat jouw post de twee grootste pluspunten van excepties boven errors bevatten? :)

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
mithras schreef op zaterdag 19 januari 2008 @ 20:59:
Ik wist dat ik het ergens eerder gelezen had, maar niet waar :p Ja klopt, dus in principe kan je zeggen dat jouw post de twee grootste pluspunten van excepties boven errors bevatten? :)
Ja, ik wist ook dat je net in dat topic geweest was, en ja dit zijn twee pluspunten. :P

Een custom error handler is misschien leuk om alle errors te laten loggen, maar je wil die handler geen onderdeel maken van je primaire foutafhandeling code, tenzij je van spaghetti houdt. ;)

{signature}

Pagina: 1