php.de

Zurück   php.de > Webentwicklung > PHP-Fortgeschrittene

PHP-Fortgeschrittene Arbeiten mit PHP ohne Einschränkungen

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 06.03.2006, 20:35  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard Entwurfsmuster: Wrapper Klasse

Hallo,
habe bisher mit Entwurfsmuster noch nicht sehr viel zu tun gehabt und
habe mich mal dran gemacht, eine Wrapper-Klasse zu schreiben um für
Projekte nach Bedarf die normalen MySQL-Funktionen von PHP zu nutzen
oder optimalerweise später über PEAR::DB (oder andere).

Wie gesagt, ist mein erster Schritt, es gibt keine Probleme in dem Sinn
und es hat auch noch keine Funktionalität.
Ich möchte eigentlich nur Wissen, ob man so eine Wrapper-Klasse
schreibt oder ob man völlig anders an die Sache rangeht:

PHP-Code:
<?php
define
('WRAPPER_DB_TYPE_STDFUNC'1);
define('WRAPPER_DB_TYPE_NB',      2); // company's db class
define('WRAPPER_DB_TYPE_DEFAULT'WRAPPER_DB_TYPE_STDFUNC);

define('WRAPPER_DB_FETCH_ASSOC',  1);
define('WRAPPER_DB_FETCH_ARRAY',  2);
define('WRAPPER_DB_FETCH_OBJECT'3);
define('WRAPPER_DB_FETCH_DEFAULT'WRAPPER_DB_FETCH_ASSOC);

/*
define('WRAPPER_DB_ERROR_IGNORE',  1);
define('WRAPPER_DB_ERROR_DIE',     2);
define('WRAPPER_DB_ERROR_DEFAULT', WRAPPER_DB_ERROR_IGNORE);
*/

class Wrapper_DB
{
    
// possible usage types
    
private $validTypes;
    private 
$type;

    private 
$validFetchTypes;
    private 
$fetchType;

    
// db object if needed
    
private $db;
    
// db connection link
    
private $link;

    private 
$methodPostfix;


    public function 
__construct($type WRAPPER_DB_TYPE_DEFAULT$fetch WRAPPER_DB_FETCH_DEFAULT)
    {
        
$this->validTypes = array(WRAPPER_DB_TYPE_STDFUNC);
        
$this->setType($type);


        
$this->validFetchTypes = array(WRAPPER_DB_FETCH_ASSOCWRAPPER_DB_FETCH_ARRAY,
            
WRAPPER_DB_FETCH_OBJECT);
        
$this->setFetchType($fetch);


        switch (
$this->type) {
        case 
WRAPPER_DB_TYPE_STDFUNC:
            
// no initial object
            
break;

        case 
WRAPPER_DB_TYPE_NB:
            
$this->db = new DB();
            break;
        }
    }


    public function 
connect($hostname$username$password)
    {
        
$method $this->getMethodname(__METHOD__);
        return 
$this->link $this->$method($hostname$username$password);
    }

    private function 
connect_stdfunc($hostname$username$password)
    {
        return 
mysql_connect($hostname$username$password);
    }

    private function 
connect_nb($hostname$username$password)
    {
        return 
$this->db->connect($hostname$username$password);
    }



    public function 
selectDB($db$link null)
    {
        if (!isset(
$link))
            
$link $this->link;

        
$method $this->getMethodname(__METHOD__);
        return 
$this->$method($db$link);
    }

    private function 
selectDB_stdfunc($db$link)
    {
        if (!isset(
$link))
            
$link $this->link;

        return 
mysql_select_db($db$link);
    }

    private function 
selectDB_nb($db$link)
    {
        return 
$this->db->selectDB($db); // $link not yet integrated
    
}



    public function 
query($sql$link null)
    {
        if (!isset(
$link))
            
$link $this->link;

        
$method $this->getMethodname(__METHOD__);
        return 
$this->$method($sql$link);
    }

    private function 
query_stdfunc($sql$link)
    {
        return 
mysql_query($sql$link);
    }

    private function 
query_nb($sql)
    {
        return 
$this->db->query($sql);
    }



    public function 
fetch($resource)
    {
        
$method $this->getMethodname(__METHOD__);
        return 
$this->$method($resource);
    }

    private function 
fetch_stdfunc($resource)
    {
        switch (
$this->fetchType) {
        case 
WRAPPER_DB_FETCH_ASSOC:
            return 
mysql_fetch_assoc($resource);

        case 
WRAPPER_DB_FETCH_ARRAY:
            return 
mysql_fetch_array($resource);

        case 
WRAPPER_DB_FETCH_OBJECT:
            return 
mysql_fetch_object($resource);
        }
    }

    private function 
fetch_nb($resource)
    {
        switch (
$this->fetchType) {
        case 
WRAPPER_DB_FETCH_ASSOC:
            return 
$this->db->fetchAssoc($resource);

        case 
WRAPPER_DB_FETCH_ARRAY:
            return 
false// not yet integrated

        
case WRAPPER_DB_FETCH_OBJECT:
            return 
false// not yet integrated
        
}
    }



    public function 
fetchInto()
    {}



    public function 
result()
    {}



    public function 
numRows()
    {}



    public function 
insertID()
    {}



    private function 
setType($type)
    {
        if (
in_array($type$this->validTypes))
            
$this->type $type;
        else
            
$this->type WRAPPER_DB_TYPE_DEFAULT;

        
$this->setMethodPostfix();
    }



    private function 
setFetchType($fetch)
    {
        if (
in_array($fetch$this->validFetchTypes))
            
$this->fetchType $fetch;
        else
            
$this->fetchType WRAPPER_DB_FETCH_DEFAULT;
    }



    private function 
setMethodPostfix()
    {
        
$this->methodPostfix '_';

        switch (
$this->type) {
        case 
WRAPPER_DB_TYPE_STDFUNC:
            
$this->methodPostfix .= 'stdfunc';
            break;

        case 
WRAPPER_DB_TYPE_NB:
            
$this->methodPostfix .= 'nb';
            break;
        }
    }



    private function 
getMethodname($methodname)
    {
        
// __METHOD__ = Wrapper_DB::Methodname, so cut first part off
        
return substr($methodname12) . $this->methodPostfix;
    }
}
?>
Oder gibt es vielleicht sogar schon gute Wrapper-Klassen die ihr erfolgreich einsetzt für PEAR::DB und die
mysql_*-Funktionen von PHP?

Übernimmt die Wrapper-Klasse zusätzliche Funktionen, also
Fehlerbehandlung etc oder muss das die jeweilige Datenbank-Klasse
übernehmen?

Gruß, c
Zergling-new ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 07.03.2006, 08:50  
Erfahrener Benutzer
 
Registriert seit: 25.04.2005
Beiträge: 1.356
HStev zeigte ein beschämendes Verhalten in der Vergangenheit
Standard

Das ist doch doppelt gemoppelt... warum extra ne Wrapper-Klasse die die PEAR DB Klasse anspricht? Soviel mehr Aufwand ist das auch nicht eine eigene zu coden ... wenn du willst lass ich dir meine Klasse mal zukommen .... ist zwar mit Sicherheit noch nicht 100% Fehlerfrei aber Ansatz sollte dir dabei sicherlich weiterhelfen.
__________________
Gewisse Dinge behält man besser für sich, z.B. das man gewisse Dinge für sich behält.
HStev ist offline   Mit Zitat antworten
Alt 07.03.2006, 08:52  
Erfahrener Benutzer
 
Registriert seit: 18.07.2004
Beiträge: 2.162
PHP-Kenntnisse:
Fortgeschritten
Basti
Standard

Ich meine, üblicher ist es, ausschließlich mit einer Instanz der jeweiligen DB-Klasse (bzw. allgemeiner: der Klasse, die es zu "wrappen" gilt) zu arbeiten (wie du es im Falle von ...TYPE_NB gemacht hast).

Die Methodenaufrufe könntest du über __call() laufen lassen.

Basti
Basti ist offline   Mit Zitat antworten
Alt 07.03.2006, 10:05  
Erfahrener Benutzer
 
Registriert seit: 21.12.2004
Beiträge: 4.651
PHP-Kenntnisse:
Fortgeschritten
mepeisen ist ein Lichtblickmepeisen ist ein Lichtblickmepeisen ist ein Lichtblickmepeisen ist ein Lichtblickmepeisen ist ein Lichtblickmepeisen ist ein Lichtblick
mepeisen eine Nachricht über ICQ schicken mepeisen eine Nachricht über Skype™ schicken
Standard

Alternativ kannst du eine Factory als Pattern verwenden. Ich finde das immer
etwas strukturierter (kommt wohl daher, dass ich von der Java/C++ Ecke
komme)...

Sprich, du hast dann vom Aufruf her etwa folgendes:
PHP-Code:
<?php
$dbcon 
DBFactory::CreateConnection(WRAPPER_DB_TYPE_DEFAULTWRAPPER_DB_FETCH_DEFAULT);
$dbcon->connect(.....

?>
Vorteil bei Factories ist auch, dass du nicht daran gebunden bist, alles auch
in eine Klasse zu packen. Du kannst die Implementierungen für einzelne
DB-Typen ordentlich auslagern in eigenständige Klassen...
mepeisen ist offline   Mit Zitat antworten
Alt 07.03.2006, 10:26  
Erfahrener Benutzer
 
Registriert seit: 18.07.2004
Beiträge: 2.162
PHP-Kenntnisse:
Fortgeschritten
Basti
Standard

Um hier (ausschließlich) eine Factory ensetzen zu können, bräuchten die einzelnen DB-Klassen ja eine gemeinsame Schnittstelle und die haben sie ja nicht, sonst bräuchte man ja keinen Wrapper. Der Wrapper hat ja genau den Job Klassen mit unterschiedlichen Schnitstellen "einzuhüllen", um den Clients eine einheitlche/gemeinsame Schnittstelle unabhängig von der dahinterliegenden Klasse anbieten zu können.

Und das "ordendliche Auslagern" der Implamentierungen der einzelnen DB-Typen ist eben meines Wissens nach auch Bestandteil des Patterns. Der Wrapper ist quasi nur der Übersetzt der Interfaces auf einen gemeinsamen Nenner und beinhaltet keine Implementierungen der Funktionalitäten, die die gewrappten Klassen bereithalten.

Basti
Basti ist offline   Mit Zitat antworten
Alt 07.03.2006, 13:15  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Zitat:
Zitat von HStev
Das ist doch doppelt gemoppelt... warum extra ne Wrapper-Klasse die die PEAR DB Klasse anspricht? Soviel mehr Aufwand ist das auch nicht eine eigene zu coden ... wenn du willst lass ich dir meine Klasse mal zukommen .... ist zwar mit Sicherheit noch nicht 100% Fehlerfrei aber Ansatz sollte dir dabei sicherlich weiterhelfen.
Ich benötige die Wrapper-Klasse weil ich mir einige wiederverwendbare Klassen schreiben möchte, die ich bei mir zu Hause (PEAR:B) und in der Firma (kein PEAR) funktionieren sollen und eventuell auf eine Datenbank zugreifen.
Was meinst du denn mit eine eigene zu coden, eine eigene Wrapper Klasse oder eigene DB Klasse? Eine eigene DB Klasse habe ich bereits (WRAPPER_DB_TYPE_NB)!
Egal was für eine du hast, schick sie mir mal, ich lese gern anderen Code und lern dabei wenn er halbwegs sauber geschrieben ist

Zitat:
Zitat von Basti
Die Methodenaufrufe könntest du über __call() laufen lassen.
Ist das denn notwendig oder üblich (besserer Stil)? Ich finde meine Variante auf den ersten Blick besser, da ich nicht in der Methode __call() alle DBTyp-spezifischen Aufrufe trennen und aufrufen müsste..
Zergling-new ist offline   Mit Zitat antworten
Alt 07.03.2006, 14:27  
Erfahrener Benutzer
 
Registriert seit: 25.04.2005
Beiträge: 1.356
HStev zeigte ein beschämendes Verhalten in der Vergangenheit
Standard

Was ich damit sagen wollte ich finds überflüssig etxra n Wrapper dafür so schreiben soviel mehr code ist das auch wieder auch nicht die MySQL Funktionen direkt in die Klasse einzubauen vor allem weiß man dann wenigsten wie die Klasse genau arbeitet.
__________________
Gewisse Dinge behält man besser für sich, z.B. das man gewisse Dinge für sich behält.
HStev ist offline   Mit Zitat antworten
Alt 07.03.2006, 17:16  
Erfahrener Benutzer
 
Registriert seit: 17.02.2006
Beiträge: 132
PHP-Kenntnisse:
Fortgeschritten
marcusson befindet sich auf einem aufstrebenden Ast
Standard

Ah, das Problemchen habe ich auch! Ich hab' 'nen Wrapper für PEAR-DB, der u.a. noch zusätzlich eine Typprüfung der Eingabedaten vornimmt und verteile das Skript kostenlos. Das Problem ist aber, dass einige wenige Leute kein PEAR-DB installiert haben, oder wegen einer verkorksten Installation nicht nutzen können.

Lösungen: Entweder PEAR-DB einfach zur Installation hinzufügen (haben einige Leute gemacht), aber ich scheue mich noch davor, weil dadurch der Download unnötig groß wird. Oder man baut in den Wrapper beides ein und schwenkt im Notfall mal fix auf die mysql-Schnittstelle um, damit das Skript nicht völlig den Dienst versagt.

Ist absolut üblich und ich für meinen Teil werde es jedenfalls genauso machen. Das erspart mir auf Dauer viele Mails ratloser User, die gar keine Ahnung haben was PEAR überhaupt ist

Ich würde allerdings nicht unbedingt alle Funktionen in der öffentlichen Schnittstelle deines Wrappers abbilden, sondern nur die wichtigsten und für die wenigen Ausnahmefälle stattdessen noch einen Bypass vorsehen. Dann bleibt deine Schnittstelle überschaubar. Von dem ganzen Mist den es da so gibt brauchst du in der Regel sowieso nur 50-70%

Kennst doch den alten Spruch: in 90% der Fälle benutzt du gerademal 10% der Funktionalität.
marcusson ist offline   Mit Zitat antworten
Alt 07.03.2006, 17:24  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

@marcusson
Genau das hatte ich auch vor, nur die wichtigsten die ich auch tatsächlich brauche.

@HStev
Es geht mir nicht um dem Mehraufwand der Implementierung der PEAR DB-Klasse in meine anderen Klassen, sondern eigentlich genau um das, was marucsson geschrieben hat.
Zergling-new ist offline   Mit Zitat antworten
Alt 07.03.2006, 18:00  
Erfahrener Benutzer
 
Registriert seit: 18.07.2004
Beiträge: 2.162
PHP-Kenntnisse:
Fortgeschritten
Basti
Standard

Es ist halt eine Frage der Herangehensweise. Letztlich ist PEAR::DB ja eine Abstraktionsschicht für eine ganze Menge an Datenbanken. Wenn nun PEAR::DB eh schon im Spiel ist und man aber irgendwas Erweitern möchte, dann sehe ich spontan nur zwei mögliche Gründe hierfür. Entweder hat man es mit einer Datenbank zu tun, für die PEAR noch keinen Treiber hat oder die Schnittstelle von PEAR taugt einem absolut nicht.

Trifft ersteres zu fände ich es angebracht, PEAR_DB einfach um den benötigten Treiber zu ergänzen (und damit womöglich auch gleich PEAR was zurückzugeben). Trifft letzteres zu, dann tut es ein einfacher Adapter, der nur die Schnittstelle von PEAR_DB übersetzt.

Ein Wapper für eine bestehende DB-Abstraktionsschicht macht in meinen Augen allerhöchstens Sinn, wenn diese Schicht später einer bereits bestehenden Anwednung hinzugefügt wird und man nicht die ganze Anwendung umschreiben möchte. Irgendwann kommt mal noch jemand auf die Idee einen PDO-Treiber für PEAR::DB zu schreiben und einen PEAR::DB-Treiber für ADOdb welche dann über einen Wrapper hinter einer Factory völlig overdosed in die Röhre guckt...

Basti

PS:
Ich seh grad: ADOdb hat tatsächlich einen PDO-Treiber. *g
Basti ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

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 are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
zentrale Klasse für Datenbankanbindung Crypi PHP Tipps 2008 4 01.07.2008 11:13
Variable aus Klasse herausbekommen GSJLink PHP Tipps 2008 7 16.02.2008 22:25
String-Parser Klasse - was muss rein? Matze PHP Tipps 2007 2 08.04.2007 22:14
Eine Klasse mehrere Dateien sn00py PHP Tipps 2006 6 08.05.2006 11:40
mehr als eine Klasse einbinden Alpha Centauri PHP-Fortgeschrittene 4 13.04.2006 20:56
aus einer funktion auf funktion anderer klasse zugreifen seejay PHP Tipps 2006 3 05.01.2006 10:37
Klasenname einer nicht instanziierten Klasse DerDesian PHP Tipps 2007 9 30.11.2005 13:13
Instanz einer Klasse in einer anderen Klasse verwenden Buhmann PHP-Fortgeschrittene 7 28.10.2005 23:12
[Erledigt] Führerschein für Klasse A+B.. Preis OK??? Off-Topic Diskussionen 20 13.07.2005 18:44
Rückgabewert auf einer Klasse anders als in der Klasse micbur PHP Tipps 2005-2 6 10.06.2005 15:06
Problem mit Übergabe einer Klasse in PHP4 PHP-Fortgeschrittene 10 08.01.2005 21:00
Klasse holt sich die Klasse PHP-Fortgeschrittene 9 07.10.2004 11:53
[Erledigt] Brauche Hilfe bei meiner ersten Klasse PHP-Fortgeschrittene 9 24.09.2004 17:09
Klassenobjet in anderer Klasse benutzen inu PHP Tipps 2004 6 19.09.2004 10:58
Klasse ändern UniQ PHP Tipps 2004 5 24.08.2004 14:46

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
wrapper klasse php, php wrapper klasse, php wrapper class, php wrapper klassen, wrapper class, wrapper entwurfsmuster, design pattern wrapper, php wrapper, wrapper klasse, php class wrapper, wrapper klassen, wrapper-klasse php, wrapper klassen php, class wrapper, wrapper class php, entwurfsmuster wrapper, wrapper html, php wrapper design pattern, eigene wrapper klasse schreiben, eigene wrapper klasse java

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




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum

Creative Commons License
Dieser Inhalt ist unter einer Creative Commons-Lizenz lizenziert.