![]() |
|
|
Themen-Optionen |
|
|
Nach oben #1 |
|
Erfahrener Benutzer
Registriert seit: 12.06.2006
Beiträge: 189
|
Hallo zusammen,
ich weiß, ich erfinde das Rad neu, aber dabei lernt man ja am besten Also: Ich möchte eine DB-Klasse schreiben. Dazu habe ich erstmal eine abstrakte Klasse definiert: PHP-Code:
MfG, FloB |
|
|
|
|
|
Nach oben #2 |
|
BIN EIN KRASSA HELD!!!111
Registriert seit: 02.06.2005
Ort: weiher im tiefsten Odenwald
Beiträge: 1.184
|
$this->connect();
im Konstruktor bringt nicht viel wenn die kompletten parameter nicht übergeben wurden! Wenn getRow die möglichkeit der entscheidung hat ob assoc, num oder object, dann sollte man das auch bei getResults wählen können ob mein Array mit assoziativen oder numerischen Arrays oder mit Objekten will. eventuell noch ne methode für affected rows ? oder fasst du das unter num_rows zusammen ? last-insert-id als methode ? kann man auch via query realisieren ... nur so als anregungen. |
|
|
|
|
|
Nach oben #3 |
|
Erfahrener Benutzer
Registriert seit: 12.06.2006
Beiträge: 189
|
Die "Parameter" werden ja als Klassenattribute gespeichert, connect() greift auf diese zu (wenn man mehrere DB-Verbindungen zu versch. DBs aufbauen will, nimmt man ja eh ein neues Objekt).
DB_OBJ kann ich noch einbauen, dachte mir aber eigentlich, dass Objekte langsamer als Arrays sind .. immer perfomant denken Bei getResult() wird noch ein DB_NUM kommen. affected rows .. hm .. eigentlich schon zusammenfassen .. ich kann ja bei mysql_query() auf true überprüfen, wenn ich affected_rows() nehmen will, anosnten num_rows(). Alles andere ist ja auch per Query möglich. Aber sonst ist das OK so? Eine Frage hab ich noch: Wenn ich den Konstruktor der Kindklasse dann aufrufe (z.B. new db_mysql($host, ..)), werden dann die Paramter in der dabase-(Abstraktions-)Klasse gespeichert oder in der Kindklasse? |
|
|
|
|
|
Nach oben #4 |
|
Entwickler
Registriert seit: 05.02.2007
Ort: München
Beiträge: 115
|
Hallo FloB,
zieh dir mal unter http://christian.zierpflanzenberatun.../apps_core.chm die CHM-Dokumentation und schau dir mal den MySQLHandler an. Vielleicht ist das eine Anregung für dich...
__________________
Grüße, Dr.E. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Have a look at http://www.adventure-php-framework.org! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
|
|
Nach oben #6 |
|
Entwickler
Registriert seit: 05.02.2007
Ort: München
Beiträge: 115
|
Hallo FloB,
zu viele private, oder zu viele öffentliche?
__________________
Grüße, Dr.E. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Have a look at http://www.adventure-php-framework.org! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
|
|
Nach oben #8 |
|
Entwickler
Registriert seit: 05.02.2007
Ort: München
Beiträge: 115
|
Hallo FloB,
wenn man doch wiederverwendbare und generische Abstraktions-Schichten designed, muss man alle benötigten Fälle abdecken und das ist hier getan...
__________________
Grüße, Dr.E. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Have a look at http://www.adventure-php-framework.org! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
|
|
Nach oben #10 |
|
Erfahrener Benutzer
Registriert seit: 04.01.2006
Ort: Kassel
Beiträge: 789
|
In meiner/meinen MySql-Klassen erwartet query() zwei Parameter:
1. die Query mit Platzhaltern (in der ersten Version nur %s, in der zweiten Version benannte Variablen: %id%, %author% etc.); 2. ein Array mit den Werten, die diese Platzhalter ersetzen sollen (im ersten Fall ein indiziertes Array mit den Werten in der richtigen Reihenfolge, im zweiten eben eine assoziatives Array). wenn du das nicht so machst (bzw. keine andere Lösung findest), musst du ja immer außerhalb der MySQL-Klasse mysql_real_escape_string() verwenden und das ist ja nicht der Sinn einer Kapselung in einer Klasse*). Letztlich geht es ja auch darum, diese Klasse durch beliebige andere SQL-Klassen austauschen zu können. Daher noch drei Punkte: - Bennene die Klasse nicht "database", sondern Database_MySQL, MySqlConnector, oder sonstwie. - Schreibe ein Interface IDatabase oder so und lass die Klasse dieses implementieren. - Erkläre mal, warum die Klasse abstrakt sein soll. Da gibts eigentlich nichts zu erweitern, sondern eher eben durch andere Klassen auszutauschen (MySqliConnector, PdoDatabase etc.). *) Seh grad, dass du eine Funktion zum Escapen anbietest. Ist dennoch einiges einfacher, wenn die du Query und Werte getrennt übergibst! Basti |
|
|
|
|
|
Nach oben #11 |
|
Erfahrener Benutzer
Registriert seit: 12.06.2006
Beiträge: 189
|
Ich habe eigentlich nur aus dem Grund eine Abstraktionsklasse geschrieben, um den Kon- und Destruktor sowie die Variablen als "private" zu definieren. Alles andere sind ja public's, deswegen werden die eh von den Kindklassen überschrieben.
Ich wollte von Anfang an festlegen, dass eine Verbindung nur anhand der Attribute der Klasse aufgebaut werden kann, also dass die Verbindungsdaten nicht als Parameter für connect() übergeben werden sollen (dürfen). Meinst du, ich hätte eher ein Interface basteln sollen? Ich habe mir bei der Planung gedacht, dass es eine Kindklasse mit dem Namen db_sql gibt, die dann entweder PDO nutzt, oder weitere Kindklassen (mit MySQL o.ä.) aufruft. Eine automatische Behandlung im Query find ich gut, aber manchmal möchte ich nicht unbedingt einen String escapen ... |
|
|
|
|
|
Nach oben #12 | ||
|
Erfahrener Benutzer
Registriert seit: 04.01.2006
Ort: Kassel
Beiträge: 789
|
Zitat:
Zitat:
PHP-Code:
Basti |
||
|
|
|
|
|
Nach oben #13 |
|
Erfahrener Benutzer
Registriert seit: 12.06.2006
Beiträge: 189
|
Nun, in der connect()-Funktion der Kindklasse db_sql könnte der Verbindungsaufbau mit PDO so aussehen:
PHP-Code:
Privat habe ich die Variablen aus dem Grund definiert, um Sicherheit zu gewährleisten. Wenn jetzt ein 3rd-Party-Modul einfach database::pass ausliest und an den Programmierer schickt, hat der User den Salat. *TODO: in der Abstraktionsklasse __get() definieren (final) und false zurückgeben / Exception werfen. |
|
|
|
|
|
Nach oben #15 |
|
Erfahrener Benutzer
Registriert seit: 12.06.2006
Beiträge: 189
|
Die Verbindugsdaten werden direkt in die Datei geschrieben - bei der Installation. var_dump() muss ich mir anschauen, denke aber, dass man das per private eben umgehen kann.
Die Reflection-Klassen muss ich mir mal anschauen .. |
|
|
|
|
|
Nach oben #16 | |
|
Entwickler
Registriert seit: 05.02.2007
Ort: München
Beiträge: 115
|
Zitat:
__________________
Grüße, Dr.E. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Have a look at http://www.adventure-php-framework.org! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
|
|
|
Nach oben #17 |
|
Erfahrener Benutzer
Registriert seit: 12.06.2006
Beiträge: 189
|
Ja - wenn die Datei beschreibbar ist. Diesen Design-Fehler nehme ich in Kauf, solange es der Sicherheit dient.
Natürlich kann man immernoch eine andere Verbindung aufbauen - dazu eine neue Instanz der Klasse anlegen (Verbindungsdaten werden an Konstruktor übergeben, der "ändert" sie). Nur kann man die Standard-Verbindungsdaten nicht erfragen! |
|
|
|
|
|
Nach oben #18 |
|
Entwickler
Registriert seit: 05.02.2007
Ort: München
Beiträge: 115
|
Hallo FloB,
in "meiner Welt" wird die MySQL-Abstraktions-Schicht mit der Methode $this->__getServiceObject() initialisiert und erhält dabei vom serviceManager automatisch den Context der Applikation. Mit Hilfe dieses Contextes kann die MySQL-Klasse dann die zugehörige Konfiguration für die Verbindungsdaten und andere Einstellungen laden. Da der Context einer Applikation jeweils für den kompletten Objektbaum zentral in der index.php geändert werden kann ist man hier absolut flexibel. Möchte man eine andere Verbindung als die Standard-Verbindung aufbauen, kann man einfach einen neuen MySQL-Treiber mit einem anderen Context erstellen. Die Möglichkeit über die Änderung der Zugangsdaten im Konstruktor ist zwar niicht verkehrt, jedoch behindert diese Tatsache dich, den Treiber singleton zu instanziieren um z.B. bessere Performance erziehlen zu können.
__________________
Grüße, Dr.E. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Have a look at http://www.adventure-php-framework.org! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
|
|
Nach oben #19 |
|
Erfahrener Benutzer
Registriert seit: 12.06.2006
Beiträge: 189
|
So firm bin ich in OOP nicht, dass ich alles in deinem Beitrag verstehen würde
Ich will nur aus Sicherheitsgründen die (Standard-)Verbindungsdaten in der Klasse privat speichern, sodass ein 3rd-Party-Modul diese nicht auslesen kann und sonst etwas anstellen kann. Bisher hab ich es so gesehen, dass die DB-Daten einmal eingetragen werden und dann nicht mehr verändert werden - Umstrukturierungen / Umzug sind Ausnahmen. Aber meint ihr, das wäre egal? Könnte man die Sicherheit irgendwie anders lösen, also praktisch in der Config-Klasse überprüfen, ob die abrufende Klasse eine Instanz von soundso ist? Wie geht das, mit instance_of()? |
|
|
|
|
|
Nach oben #20 |
|
BIN EIN KRASSA HELD!!!111
Registriert seit: 02.06.2005
Ort: weiher im tiefsten Odenwald
Beiträge: 1.184
|
das klingt ja so, wie wenn du wild-fremden php-code zusätzlich zu deinem laufen lässt. das 3rd-Party-Modul, das deine Daten will um sie weiterzuversenden bekommt sie recht einfach indem es die Datei via fopen öffnet, oder var_dump nutzt oder sonst irgendwas und wenn es was böses in der datenbank machen will, nutzt es einfach die instanz deiner datenbankklasse.
|
|
|
|