Ola,

Nog weer even een leuke...

Stel we hebben een of andere (algemene) copy functie. Als deze false teruggeeft (het kopiëren is mislukt) wil ik een exception gooien. Weer even uit nieuwsgierigheid. Heeft voorbeeld A of voorbeeld B jullie voorkeur?

A:

<?php
if (!copy('foo.php', 'bar.php')) {
throw new Exception('could not make copy bla bla bla...');
}
?>


B:

<?php
if (copy('foo.php', 'bar.php')) {
return;
}
throw new Exception('could not make copy bla bla bla...');
?>
In voorbeeld A zeg ik "als het kopiëren is mislukt gooi dan een exception. In voorbeeld B zeg ik "als het kopiëren is GELUKT verlaat dan de functie. Als het kopiëren dan mislukt dan wordt er niet gereturned en wordt alsnog de exception gegooid. Twee verschillende benaderingswijzen. Methode A voelt denk ik het meest intuïtief en prettig, maar methode B is weer ietsje sneller. Ik weet dat veel mensen voor methode A zouden kiezen, maar ik ben benieuwd of hier ook programmeurs zijn die juist vaker een oplossing a la methode B gebruiken. Van de 2 is methode B dus ietsje sneller (omdat er een positieve vergelijking plaatsvindt in plaats van een negatieve vergelijking zoals bij A). Wat heeft jullie voorkeur?
Optie B is beter, vooral als je er nog een else aan toevoegt voor alle overige gevallen.

De argumentatie "als het geen directory is, dan moet het een bestand zijn" in A is namelijk een drogreden van het uitgesloten midden.
Ward, thanks voor je reactie. Echter, in dit geval kan $path niks anders zijn dan een path, omdat ik het uitlees vanuit een andere directory. Vind je optie B dan nog steeds de beste?

Stel we hebben een functie die true of false teruggeeft, bijv. copy();

<?php
$success = copy('foo', 'bar');
?>
Zou jij in deze vergelijkbare situatie dan ook dit doen?

<?php
$success = copy('foo', 'bar');
if ($succes) {
//kopiëren gelukt
} elseif (!$succes) {
// kopiëren mislukt
} else {
// kopiëren niet gelukt en ook niet mislukt
}
?>
Dit is toch een beetje vreemd :-s
Als het resultaat uitsluitend true of false is, is het natuurlijk een if/else. Volgens de formele logica kun je dan toch nog last hebben van de wet van de uitgesloten derde of het uitgesloten midden:


<?php
if ($succes) {
    // Toestand A: true
} else {
    // Toestand B: niet true, dus onder andere false
}
?>

De else wordt hier niet getriggerd op false, maar ruimer op alles dat niet true is. Dat is niet per se hetzelfde wanneer $succes bijvoorbeeld null of undefined zou kunnen zijn.

Daarom lijkt de volgende controlestructuur naar dezelfde twee toestanden A en B te leiden, maar is de achterliggende logica toch een heel andere:


<?php
if (false == $succes) {
    // Toestand B: false, dus onder andere niet true
} else {
    // Toestand A: niet false, dus onder andere true
}
?>


Lol, maar in het geval $succes een boolean is, maakt het dus helemaal niks uit ;)
Ozzie, maar strict genomen kun je in PHP er nooit vanuit gaan dat $succes een boolean is. En hier komen we dus op het grootste probleem wanneer je complexe scripts gaat schrijven: Het is lazy typed.

In Java of elke andere strict typed taal zou het gebruik van if..else voldoende zijn:
bool succes;
if (true == succes) {
    // Toestand A: true
} else {
    // Toestand B: false
}
Correct Wouter, maar een functie zoals copy() kan toch alleen maar een boolean teruggeven?
Ozzie, wie zegt dat? De copy functie kan alles terug geven, alleen PHP.net vertelt ons dat het alleen een boolean is. Maar aangezien het PHP is mag het alles zijn, dus kan het ook alles zijn.

Maar goed, nu gaan we wel echt heeeel erg strict nadenken over de code en wanneer we dat gaan doen moeten van PHP eigenlijk een static typed language maken (dus niet lazy en niet strict)
Maar php.net is toch de officiële documentatie? Kunnen we die niet vertrouwen?
Ozzie, jij bekijkt het nog veel te simpel. In PHP kun je nergens een functie limiteren tot een bepaalde type, je kunt alleen documentatie (dingen die mensen hebben geschreven) gebruiken om het type te weten. En hoewel we best PHP.net kunnen vertrouwen (nou ja...), kan je in de code dus nooit met zekerheid zeggen welk type je nou terug krijgt.

Reageren