Portal > Foren > PHP > PHP-Programmierung > Designfrage zu Exceptions in PHP5
Antwort
 
Themen-Optionen Thema durchsuchen
Alt 01.05.2007, 10:06 Nach oben    #1
Christian Mühlroth
 
Benutzerbild von Chr!s
 
Registriert seit: 04.09.2005
Ort: Nürnberg
Beiträge: 561
Standard Designfrage zu Exceptions in PHP5

Tag,
ich habe mal eine generell Frage zu Exceptions in PHP5. Ich habe ja jederzeit die Möglichkeit, selbstdefinierte Exceptions zu erstellen (ClassDoesNotExistException, etc..).
Da ich gerade am Aufbau meines Frameowrks bin brauche ich natürlich auch einige Exceptions.

Derzeit habe ich bereits einige Exceptions wie NotSupportedException, ClassDoesNotExistException, UnableToEstablishConnectionException usw. implementiert, jedoch sieht es in den Exceptions immer gleich aus:
PHP-Code:
<?php
/**
 * The "ClassDoesNotExistException" will be thrown when a class is requested,
 * but the class is not registered (yet).
 *
 * @author Christian Mühlroth
 * @version 1.0
 */
class ClassDoesNotExistException extends ExceptionHandler {
        
/**
         * The costructor of the exception (will be called automatically)
         *
         * @access public
         * @param string $sMessage
         * @param integer $iCode
         * @return void
         */
        
public function __construct($sMessage$iCode 0) {
                
// At first make sure the core exception is initialized properly
                
parent::__construct($sMessage$iCode);
        }

        
/**
         * Renders the exception-view
         *
         * @access public
         * @return void
         */
        
public function render() {
                
parent::render();
        }

        
/**
         * Renders the exception-view, but only a little notice
         *
         * @access public
         * @return void
         */
        
public function renderNotice() {
                
parent::renderNotice();
        }
}
?>
Bei mir übernimmt die Klasse ExceptionHandler quasi die ganze Arbeit, von daher sind die abgeleiteten Exceptions eigentlich sinnlos und nur nötiger Balast - ich persönlich find das aber besser eine ClassDoesNotExistException als eine normale Exception zu werfen.

Nun hab ich mehrere Fragen:
1.) Ab wann ist es sinnvoll, abgeleitete Exceptions zu erstellen? Ist es in meinem Fall auch sinnvoll, oder sind diese schon zu speziell? (QueryFailureException, NoConnectionEstablishedException, FileIsCorruptedException, NoTemplateWasLoadedYetException ..) Soll ich besser ModelException, ViewException etc verwenden?

2.) Wenn ich viele Exceptions habe (derzeit sind es 10 verschiedene), ab wann wird es lästig für den Server?

Oder besser: Wie vermeide ich, dass ich alle Exceptions am Anfang des Scripts in den Speicher laden muss? Ich könnte natürlich die __autoload() Funktion verwenden, aber derzeit ist diese nur für "normale" Klassen da, nicht für Exceptions. Die Exceptions befinden sich in "/exceptions/", die "normalen" Klassen dagegen in "/library/".

Wenn ich nun den Exception-Pfad in die __autoload() Fukntion mit einbezieh, dann wird ja jedesmal wenn ich eine "normale" Klasse lade, auch zu erst in dem exceptions-Ordner nachgesehn - das verbraucht mir dann auch zu viel Performance.
Gibt es dafür eine gute Lösung?
__________________
http://www.ChrisDiary.De

Geändert von Chr!s (01.05.2007 um 10:24 Uhr)
Chr!s ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 01.05.2007, 17:14 Nach oben    #2
Jonas
 
Benutzerbild von Artemis
 
Registriert seit: 03.06.2006
Beiträge: 244
Standard

zu 2:

Ganz einfach. Du guckst einfach, ob der Klassenname mit "Exception" endet und lädst dann aus dem exception-Ordner, ansonsten machst du dass, was du bisher machst.
__________________
Applikations-Programmierung:
BlitzMax, BlitzPlus

Webentwicklung:
PHP, (X)HTML, CSS, JavaScript, MySQL


Artemis ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 02.05.2007, 10:19 Nach oben    #3
Bastian Fenske
 
Registriert seit: 04.01.2006
Ort: Kassel
Beiträge: 853
Standard

Bei mir folgen Exceptions dem selben Namensschema, wie alle anderen Klassen und beginnen alle mit "Exception_". So findet __autoload() diese auch alle um /lib/Exception/ und es ist keine spezielle Handhabung notwendig.

Wieso implementierst du denn in den konkreten Exceptions Methoden, die nichts anderes machen, als die Methoden des Elternobjektes aufzurufen? Folgendes würde hier doch reichen:
PHP-Code:
<?php

class Exception_Something extends Exception_Base {}
Um den Speicher brauchst du dir keinen Kopf zu machen, wenn du __autoload() verwendest. Wenn eine Exception tatsächlich geworfen wird, ist es eh Wurscht.

Und, warum leitest du Exceptions von einer Klasse ExceptionHandler ab? Entweder handelt es sich um eine Exception oder um eine Klasse, die mit Exceptions dealt.

Basti
Basti ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 02.05.2007, 13:09 Nach oben    #4
Christian Mühlroth
 
Benutzerbild von Chr!s
 
Registriert seit: 04.09.2005
Ort: Nürnberg
Beiträge: 561
Standard

Zitat:
Zitat von Basti
Wieso implementierst du denn in den konkreten Exceptions Methoden, die nichts anderes machen, als die Methoden des Elternobjektes aufzurufen?
Das ist allerdings eine berechtigte Frage. Da hab ich wohl nich aufgepasst.
Zitat:
Zitat von Basti
Um den Speicher brauchst du dir keinen Kopf zu machen, wenn du __autoload() verwendest. Wenn eine Exception tatsächlich geworfen wird, ist es eh Wurscht.
Mittels __autoload() werden auch Klassen geladen, die keine instanziierung verlangen und somit vom Repository ( = Klassenverwaltung im Framework) nicht geladen werden. Aber ich hab da schon einen Lösungsansatz, danke für den Denkanstoß.
Zitat:
Zitat von Basti
Und, warum leitest du Exceptions von einer Klasse ExceptionHandler ab? Entweder handelt es sich um eine Exception oder um eine Klasse, die mit Exceptions dealt.
ExceptionHandler ist bei mir die Klasse, in der alles der Exceptions zusammeläuft - das ggf. rendering der exceptions, und das loggen. Zudem lasse ich mir so weitere Möglichkeiten offen, später noch mehr dort einzubauen.
__________________
http://www.ChrisDiary.De
Chr!s ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 02.05.2007, 14:06 Nach oben    #5
Bastian Fenske
 
Registriert seit: 04.01.2006
Ort: Kassel
Beiträge: 853
Standard

Zitat:
Zitat von Chr!s Beitrag anzeigen
Zitat:
Zitat von Basti
Um den Speicher brauchst du dir keinen Kopf zu machen, wenn du __autoload() verwendest. Wenn eine Exception tatsächlich geworfen wird, ist es eh Wurscht.
Mittels __autoload() werden auch Klassen geladen, die keine instanziierung verlangen und somit vom Repository ( = Klassenverwaltung im Framework) nicht geladen werden.
Verstehe ich nicht. __autoload() hat ja nichts weiter zu tun, als die entsprechende Datei mit der Klassendefinition einzubinden. Die Instanzierung bzw. der Zugriff auf statische Klassen geschieht doch eh an anderer Stelle. Wenn du bestimmte Klassen hast, die vor der Instanzierung bzw. dem statischen Zugriff über statische Methoden mit bestimmten Inhalten "geimpft" werden müssen, dann löse das besser über ein Interface. Irgendwie so:
PHP-Code:
<?php

function __autoload($sClassName)
{
    
// include file ...

    
if (in_array('IContainsConfig'class_implements($sClassName)))
        
$sClassName::setConfig(Config::getInstance());
}
Ist aber sicher keine sehr saubere Lösung ... schwer zu testen etc.

Zitat:
Zitat:
Zitat von Basti
Und, warum leitest du Exceptions von einer Klasse ExceptionHandler ab? Entweder handelt es sich um eine Exception oder um eine Klasse, die mit Exceptions dealt.
ExceptionHandler ist bei mir die Klasse, in der alles der Exceptions zusammeläuft - das ggf. rendering der exceptions, und das loggen. Zudem lasse ich mir so weitere Möglichkeiten offen, später noch mehr dort einzubauen.
Dafür gibt es die Funktion set_exception_handler(). Ich würde da tatsächlich unterscheiden, zwischen der Exception, die durch ihren Typ (Klasse) die Art der Ausnahme angibt und entsprechende Infos enthält auf der einen Seite und, auf der anderen Seite, einer Klasse, die mit einem solchen Objekt umgeht, also die Werte ausliest und entsprechend verarbeitet (Logging, Ausgabe, E-Mail-Benachrichtigung). Letztere ist wohl am geschicktesten einfach nur ein leeres "beobachtbares Subjekt", bei dem sich - je nach Modus (dev, debug, productive, wasauchimmer) - verschiedene Observer einklinken können (Logger, "E-Mail-Benachrichtiger", etc.).

Basti

PS:
Ich würde es vermeiden, Umlaute (bzw. Nicht-ASCII-Zeichen) im Quellcode zu verwenden, deinen Namen also eher als "Christian Mehhlroth" angeben. Damit vermeidest du Zeichensalat, wenn andere an deinem Code mitarbeiten, deren Editoren einen anderen Zeichensatz eingestellt haben, als der deinige.
Basti ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 03.05.2007, 22:42 Nach oben    #6
Christian Schuhmann
 
Benutzerbild von bobby
 
Registriert seit: 09.03.2007
Ort: Nürnberg
Beiträge: 66
Standard

Zitat:
Zitat von Basti Beitrag anzeigen
Dafür gibt es die Funktion set_exception_handler(). Ich würde da tatsächlich unterscheiden, zwischen der Exception, die durch ihren Typ (Klasse) die Art der Ausnahme angibt und entsprechende Infos enthält auf der einen Seite und, auf der anderen Seite, einer Klasse, die mit einem solchen Objekt umgeht, also die Werte ausliest und entsprechend verarbeitet (Logging, Ausgabe, E-Mail-Benachrichtigung). Letztere ist wohl am geschicktesten einfach nur ein leeres "beobachtbares Subjekt", bei dem sich - je nach Modus (dev, debug, productive, wasauchimmer) - verschiedene Observer einklinken können (Logger, "E-Mail-Benachrichtiger", etc.).
Ich kann mir zwar ungefähr vorstellen wie das aussehen könnte, aber wärst du so nett und gibst mir ein kleines Beispiel (Klassengerüst) ?

bobby
bobby ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 04.05.2007, 00:20 Nach oben    #7
Bastian Fenske
 
Registriert seit: 04.01.2006
Ort: Kassel
Beiträge: 853
Standard

Sowas in der Art eben:

PHP-Code:
<pre>
<?php

interface IExceptionObserver
{
    public function 
notify(Exception $Exception);
}

class 
Logger implements IExceptionObserver
{
    protected 
$sPath;

    public function 
__construct($sPath)
    {
        
$this->sPath $sPath;
    }

    public function 
log($sMessage)
    {
        echo 
"Not implemented yet: Logger::log()\n";
        echo 
"Logfile: $this->sPath\n";
        echo 
"Message: $sMessage\n\n";
    }

    public function 
notify(Exception $Exception)
    {
        
$this->log($Exception->__toString());
    }
}

class 
Observerable
{
    private 
$aObservers = array();

    public function 
registerObserver(IExceptionObserver $Observer)
    {
        
$this->aObservers[] = $Observer;
    }

    protected function 
notifyObservers($m)
    {
        foreach (
$this->aObservers as $Observer)
            
$Observer->notify($m); 
    }
}


class 
ExceptionHandler extends Observerable
{
    public function 
__construct()
    {
        
set_exception_handler(array($this'handleException'));
    }

    public function 
handleException(Exception $Exception)
    {
        
$this->notifyObservers($Exception);
    }
}

class 
Exception_Example extends Exception
{
}

$ExceptionHandler = new ExceptionHandler;

$Logger = new Logger('/path/to/logfile.log');
$ExceptionHandler->registerObserver($Logger);

$Logger2 = new Logger('/another/logfile.log');
$ExceptionHandler->registerObserver($Logger2);

throw new 
Exception_Example('foo');
throw new 
Exception_Example('bar');
Allgemeiner ist es natürlich sinniger, einen ErrorHandler zu schreiben, der eben auch die Exceptions handhabt.

Basti

Geändert von Basti (04.05.2007 um 00:32 Uhr)
Basti ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 05.05.2007, 12:09 Nach oben    #8
Christian Mühlroth
 
Benutzerbild von Chr!s
 
Registriert seit: 04.09.2005
Ort: Nürnberg
Beiträge: 561
Standard

Zitat:
Zitat von Artemis Beitrag anzeigen
zu 2:

Ganz einfach. Du guckst einfach, ob der Klassenname mit "Exception" endet und lädst dann aus dem exception-Ordner, ansonsten machst du dass, was du bisher machst.
Im übrigen Danke dafür, damit hab ich nochmal einiges an Ladezeit gutmachen können!

Ich hab jetzt dazu eine Lösung gefunden, die zufriedenstellend ist und super funktioniert.
__________________
http://www.ChrisDiary.De
Chr!s ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
PingBacks sind an
RefBacks sind aus

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
[Grundsatzfrage] Exceptions bzw. Fehlerbehandlung bobby PHP-Programmierung 4 26.03.2007 23:54
Apache und PHP5 Julied64 Tools, Server, Betriebssysteme 14 08.07.2006 17:04
Professionelle Softwareentwicklung mit PHP5 Prophet Literatur 0 06.06.2006 12:14
php5 pdf klasse? ex³ PHP-Programmierung 4 19.02.2006 12:41


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:15 Uhr.


Powered by vBulletin® Version 3.7.4 (Deutsch)
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45