Donnerstag, 12. Mai 2011

Logdatei - mehr Gimmicks zum gleichen Preis!

Niemand soll sagen ich würde nicht auf Kritik reagieren. Deshalb ist die bereits an dieser Stelle vorgestellte Klasse zum Protokollieren noch einmal etwas aufpoliert worden. Alles verchromt, tiefergelegt und zum gleichen Preis mit noch mehr Gimmicks - als Singleton und mit Fehlerbehandlung.


Die Klasse LogDatei protokolliert Einträge direkt oder gesammelt in eine angegebene Logdatei oder versendet sie per eMail.

Für einen breiteren Zugriff als in der originalen Form ist die Klasse als Singleton realisiert. Ein Singleton ist (vereinfacht) ausgedrückt eine Klasse von der nur eine einzige Instanz existieren kann. Andere Klassen können sich eine Instanz zur Verwendung erschaffen, greifen aber damit letztendlich nur auf die bereits bestehende Instanz zu. Das alte Motto "es kann nur einen geben" bekommt hier eine ganz neue, objektorientierte Bedeutung.

Darüberhinaus werden Fehlermeldungen und Warnungen von PHP in eine Methode der Klasse LogDatei umgeleitet und protokolliert. Treten Fehler auf, werden Sie so automatisch in der Logdatei vermerkt und zusätzlich gesammelt per eMail verschickt.

//Logdatei mit Fehlerprotokollierung

/*
 * $Obj = LogDatei::singleton('Pfad:/Datei.txt');
 * oder als Objektvariable innerhalb einer Klasse
 * private KlassenVariable
 * $this->KlassenVariable = LogDatei::singleton('Pfad:/Datei.txt');
 * dann Aufruf als $this->KlassenVariable->Methode();
 *
 * Constructor erwartet beim ersten Aufruf Dateinamen einer
 * anzulegenden oder vorhandenen Log-Datei
 * die() falls die Datei nicht geoffnet werden kann
 * Verweist immer auf die einzige Instanz, nur erste gesetzte Datei
 * wird verwendet
 *
 *
 * $Obj->protokolliereFehler();
 * Wird bereits im constructor aktiviert
 * Keine Pruefung ob Fehlerhandle bereits
 * umgeleitet, da dies auch gewollt sein kann
 * $Obj->stoppeFehlerProtokoll();
 * nicht ganz korrekt, setzt auf den vorherigen Fehlerhandle zurueck
 *
 * $Obj->setMail('e@mail.xyz');
 * $Obj->setSMTP('smtp')
 *
 * $Obj->schreibe('Inhalt');
 * $Obj->_('Inhalt');
 * Kurzform von schreibe()
 * $Obj->schreibeMitZeit('Inhalt');
 * $Obj->maile('Inhalt');
 *
 * $Obj->merke('Inhalt');
 * $Obj->flush();
 * $Obj->flushToMail();
 *
 * Destructor fuehrt flush durch und versendet Fehler als eMail
 *
*/
class LogDatei
{
    private static $instance;
    private $Datei;
    private $Mail = 'e@mail.xyz';
    private $Merker;
    private $Fehler;

    // clone wird fuer das Singleton gesperrt
    private function __clone()
    {

    }

    //Die Funktion ersetzt quasi den Konstruktor und laesst nur
    //die Erschaffung einer Instanz zu.
    public static function singleton($Wert = 'NotLogfile.txt')
    {
        if (!self::$instance)
        {
            self::$instance = new self($Wert);
        }
        return self::$instance;
    }

    //Der Konstruktor ist private und damit von aussen
    //nicht mehr direkt zu erreichen. Es wird geprueft
    //ob die Logdatei geoeffnet werden kann.
    private function __construct($Datei)
    {
        $test = fopen($Datei, "a");
        if ($test)
        {
            fclose($test);
            $this->Datei = $Datei;
        } else
        {
            die('PANIK: LogDatei kann nicht geschrieben werden!');
        }

        $this->_("\r\n");
        $this->schreibeMitZeit('BEGINN VERARBEITUNG');
        $this->protokolliereFehler();
    }

    //Bei der Beendigung werden noch vorhandene Inhalte
    //geschrieben, Fehler als eMail verschickt.
    public function __destruct()
    {
        if ($this->Merker)
        {
            $this->flush();
        }
        if ($this->Fehler)
        {
            $this->maile($this->Fehler);
        }
        $this->schreibeMitZeit('ENDE VERARBEITUNG');
    }

    //Schreiben als Kurzform
    public function _($Inhalt)
    {
        $this->schreibe($Inhalt);
    }

    //Alle gemerkten Inhalte werden geschrieben und
    //danach geloescht
    public function flush()
    {
        $this->schreibe($this->Merker);
        $this->Merker = '';
    }

    //Alle gemerkten Inhalte werden als eMail verschickt und
    //danach geloescht
    public function flushToMail()
    {
        $this->maile($this->Merker);
        $this->Merker = '';
    }

    //Inhalte werden nicht direkt in die Logdatei geschrieben
    //sondern "gemerkt"
    public function merke($Inhalt)
    {
        $this->Merker .= "\r\n" . $Inhalt;
    }

    //Die EMail-Adresse kann festgelegt werden
    public function setMail($Mail)
    {
        $this->Mail = $Mail;
    }

    //SMTP kann gesetzt werden
    public function setSMTP($SMTP)
    {
        ini_set('SMTP', $SMTP);
    }

    //Der uebergebene Inhalt wird per eMail verschickt,
    //optional kann ein Betreff angegeben werden
    public function maile($Inhalt, $Betreff = 'Info von LogDatei')
    {
        $betreff = 'Info von LogDatei';
        $Ergebnis = mail($this->Mail, $betreff, $Inhalt, "From: ab@sender.xyz\nContent-Type: text/html\nCC: user@empfaenger.xyz\n");

        if ($Ergebnis == false)
        {
            $this->schreibeMitZeit('PANIK: eMail konnte nicht verschickt werden!');
        }
    }

    //Der Inhalt wird direkt in die Logdatei geschrieben
    public function schreibe($Inhalt)
    {
        $datei = fopen($this->Datei, "a");
        fwrite($datei, "\r\n" . $Inhalt);
        fclose($datei);
    }

    //Der Inhalt wird direkt mit einer Zeitangabe in die Logdatei geschrieben
    public function schreibeMitZeit($Inhalt)
    {
        $datei = fopen($this->Datei, "a");
        fwrite($datei, "\r\n" . date('d.m.H:i > ') . $Inhalt);
        fclose($datei);
    }

    //Alle Fehlermeldungen und Warnungen werden der Methode "FehlerKanal"
    //uebergeben
    public function protokolliereFehler()
    {
        set_error_handler(array($this, 'FehlerKanal'));
    }

    //Setzt Fehlerhandle nicht auf Standard, sondern auf zuvor
    //verwendeten Handle zurueck
    public function stoppeFehlerProtokoll()
    {
        restore_error_handler();
    }

    //Alle Fehlermeldungen werden in die Logdatei geschrieben und
    //zusaetzlich fuer einen spaeteren Versand per eMail zwischengespeichert
    public function FehlerKanal($Fehlerstufe, $Meldung, $Datei, $Zeile, $DetailArray)
    {
        //DetailArray wird hier nicht ausgewertet
        $FehlerMeldung = 'FEHLER: ' . $Fehlerstufe . ' ' . $Meldung . ' in ' . $Datei . ' Zeile ' . $Zeile;
        $this->_($FehlerMeldung);
        $this->Fehler .= "\n".date('H.i.s')."\n".$FehlerMeldung;
    }
}
Empfehlenswert sind in diesem Zusammenhang folgende Links über den Errorhandler in PHP: http://www.w3schools.com/php/php_error.asp
http://www.olate.co.uk/articles/249
http://www.phpdig.net/ref/rn19re268.html
http://www.phpdig.net/ref/rn19re267.html
http://www.dynamic-webpages.de/php/ref.errorfunc.php

Wer mehr zu dem Thema Singleton erfahren möchte sei auf
http://de.wikipedia.org/wiki/Singleton_%28Entwurfsmuster%29 verwiesen.

Und nach wie vor ohne Gewähr...

Keine Kommentare:

Kommentar veröffentlichen