phpbar.de logo

Mailinglisten-Archive

[php] goto statements

[php] goto statements

Johannes Schlueter schlueter at phpbar.de
Son Aug 1 02:36:01 CEST 2004


On Sunday 01 August 2004 00:22, Hinrich Donner wrote:
> > On Saturday 31 July 2004 12:15, Hinrich Donner wrote:
> >
> > Wer goto nicht nutzen moechte, wird nicht dazu gezwungen....;-)

Doch: Wenn man an einem Projekt weiterarbeiten will/soll/muss/darf in dme ein 
vorheriger PRogrammierer goto missbraucht hat.

> > Es soll Leute geben, die das sinnvoll einsetzten können...
>
> Ja, weil sie wahrscheinlich andere Sprachkonstrukte nicht sinnvoll
> einsetzen können.

Oder weil sie goto richtig einsetzen können. Bis heute hielt ich goto auch für 
recht veraltet und selten gebraucht - obgleichich wusste, dass man es häufig 
doch gut gebrauchen kann. Inzwischen habe ich ein wenig recherchiert und in 
eigentlich jedem C (nicht C++) Source mit mehr als 1000 Zeilen habe ich gotos 
gefunden (z.B. 44x im Apache 1.3, 2003 mal im aktuellen xorg-X-Server, ... 
Meßmethode habe ich in nem anderen Posting heute Nahcmittag schon angegeben), 
so ausgefallen kann es also nicht sein, zumindest in C und C ist nicht PHP.

Aber aus neugier mal folgendes Problem: Es soll eine PHP-Funktion (nicht 
Methode *g*) entwickelt werden, die eine Datenbank-Transaktion startet ein 
paar SQL-Queries absetzt, ein paar Berechnungen durchführt, dann wieder ein 
paar SQL-Queries absetzt usw. Wenn irgendwo ein Fehler auftritt soll so früh 
wie möglich abgebrochen werden und Transaktion zurück genommen werden und ein 
log-Eintrag geschrieben werden. Bei Erfolg gibt die Funktion true sonst false 
zurück.

<?php
function foobar() {
    begin_transaction();
    
    $result = db_query('SELECT foo, bar FROM tabelle1 WHERE id=2');
    if (!$result) {
         goto error;
    }
    $row = db_fetch_row($result);

    $result = db_query('UPDATE tabelle1 SET foo=1024, bar=23 WHERE id=2');
    if (!$result) {
        goto error;
    }

    $result = db_query('UPDATE tabelle2
                                   SET ergebnis='.($row[0]+$row[2]).' 
                                   WHERE id=2');
    if (!$result) {
        goto error;
    }

// .....
   commit_transaction();
   return true;

error:
    error_log(db_error());
    transaction_rollback();
    return false;
}
?>

Hier finde ich das goto wunderbarklar und ÜBersichtlich. Was wären die 
Alternativen?
  - am Anfang ein "try {", statt "goto error" je ein "throw new 
Exception('foobar');" und am Ende ein "} catch Exception $w { error_log; 
rollback();" - wie ich schonmal schrieb: Ein imho blöder Paradigmen-Wechsel.
  - Am Anfang ein "do {" statt "goto error" je ein "break;" und am Ende ein 
"return true; } while(0); error_log(...); rollback(); return false;" - Das 
ist wohl ein Missbrauch der "do { ... } while" Schleife
  - Eine Fehlerfunktion, die statt der "goto error" mit "return 
my_error_function(db_error());" aufgerufen wird - auch nicht besonders 
übersichtlich und wenn man im Fehlerfall mit mehreren Reosurcen Arbeiten will 
eine lange Parameterliste
  - Die Fehlerbehandlungsroutinen gleich zur Fehlerquelle und dann gleich 
return false - dass das dumm ist, darüber müssen wir uns ja wolh nicht 
unterhalten.

Sonst noch Vorschläge? Habe ich zu später Stunde was übersehen?

> Hinrich Donner

johannes
-- 
Johannes Schlüter                                     http://schlueters.de
php::bar | Der Treffpunkt für Einsteiger und Profis   http://www.phpbar.de

php::bar PHP Wiki   -   Listenarchive