| PHP Developer Forum Hier habt ihr die Möglichkeit, eure Skriptprobleme mit anderen Anwendern zu diskutieren. Seid so fair und beantwortet auch Fragen von anderen Anwendern. Dieses Forum ist sowohl für ANFÄNGER als auch für PHP-Profis! Post your PHP questions here! |
 |

03-08-2008, 16:48
|
|
INC.
Registrierter Benutzer
|
|
Registriert seit: Nov 2005
Beiträge: 106
|
|
Frage zu Klassenstruktur
Hallo erstmal
Also ich bin gerade dabei eine Klasse zu schreiben, deren Methoden Zugriff auf eine MySQL-Db benötigen. Und wenn schon objekt-orientiert, dann soll für den DB-Zugriff Das Modul mysqli zum Einsatz kommen.
Meine Idee zur Vorgehensweise ist folgende: da eh jede Methode meiner Klasse DB-Zugriff benötigt, wollte ich im Konstruktor ein neues mysqli-Objekt erzeugen und dann im Destruktor mysqli->Close() aufrufen. Die Methoden müssen sich dann weder um die Herstellung noch das Trennen der Verbindung bemühen, sondern sollen direkt mit dem im Konstruktor erzeugten mysqli-Objekt Arbeiten können.
Ist diese Vorgehensweise sinnvoll, oder sollte sich jede einzelne Methode selbst um die Verbindung kümmern?
Dann habe ich noch eine Frage zur Sichtbarkeit des im Konstruktor erzeugten mysqli-Objekts. Bisher ist dieses ja nur innerhalb des Konstruktors sichtbar, die anderen Methoden sollen ja allerdings auch Zugriff darauf haben. Muss ich also außerhalb des Konstruktors schon so etwas wie "$db = new Object()" deklarieren, welches ich dann innerhalb des Konstruktors mit mysqli initialisiere, oder was ist da die beste Lösung?
Danke schonmal
Geändert von INC. (03-08-2008 um 16:50 Uhr)
|

03-08-2008, 17:09
|
|
combie
PHP Expert
|
|
Registriert seit: May 2006
Beiträge: 2.925
|
|
Das muß man nicht mehr selber bauen...
Es gibt ja schon "doctrine" usw.
Dir reicht doch bestimmt 1 Verbindung zur DB.
Also ist es Unsinn, wenn jedes Object seine eigene Aufbaut.
|

03-08-2008, 17:09
|
Kropff
  Administrator
|
|
Registriert seit: Mar 2002
Ort: Köln
Beiträge: 11.308
|
|
Zitat:
|
Ist diese Vorgehensweise sinnvoll, oder sollte sich jede einzelne Methode selbst um die Verbindung kümmern?
|
wieso. da hast du schon so schöne dinge wie den konstruktor und destruktor, also nutze sie auch.
Zitat:
|
Bisher ist dieses ja nur innerhalb des Konstruktors sichtbar
|
wenn du sie als private deklariert hast.
Zitat:
|
die anderen Methoden sollen ja allerdings auch Zugriff darauf haben
|
die verbindung kann ruhig private sein. siehe beispiel-/pseudo-code
PHP-Code:
class MySQL
{
private $con;
private $result;
public function __construct ($host, $user, $password, $database)
{
$this -> con = mysql_connect ($host, $user, $password);
if (is_resource ($this -> con))
{
mysql_select_db ($database);
}
}
public function __destruct ()
{
if (is_resource ($this -> con))
{
mysql_close ($this -> con);
}
}
public function doQuery ($query)
{
if ($this -> result = mysql_query ($query))
{
while ($row = mysql_fetch_assoc ($this -> result))
{
...
}
}
}
}
peter
__________________
Nukular, das Wort ist N-u-k-u-l-a-r (Homer Simpson)
Meine Seite
|

03-08-2008, 20:17
|
|
INC.
Registrierter Benutzer
|
|
Registriert seit: Nov 2005
Beiträge: 106
|
|
Danke euch beiden. Jetzt bleibt noch ein Problem, welches ich gerade nicht durchschauen kann, und zwar das Schlüsselwort "this".
In richtigen Programmiersprachen (C# etc..) verwendet man "this", um Namenskonflikte mit lokalen Variablen zu vermeiden.
Gibt es eine Eigenschaft UND eine lokale Variable innerhalb eines Objekts/Klasse, welche exakt den selben Namen haben, so kann man die Eigenschaft über "this.Namen" und die lokale Variable nur über "Namen" ansprechen.
Gibt es jedoch keine lokale Variable mit dem selben Namen, so braucht man kein "this", um die Eigenschaft anzusprechen, sondern kann einfach nur "Namen" schreiben (so wie man es zuvor mit der lokalen Variablen gemacht hat, als diese noch existierte).
Kurz gesagt: gibt es keine lokale Variable, die so heißt wie eine Eigenschaft, braucht man "this" auch niemals benutzen.
In PHP scheint dies aber irgendwie anders zu sein. Mein Destruktor sieht so aus:
PHP-Code:
public function __destruct()
{
if ($mysql instanceof mysqli) {
$mysql->close();
}
}
$mysql habe ich übrigens zur Eigenschaft gemacht wie von Kropff vorgeschlagen, sie ist im Desktruktor also eigentlich bekannt. Das ganze geht nur nicht! Ändere ich den Code aber so ab:
PHP-Code:
public function __destruct()
{
if ($this->mysql instanceof mysqli) {
$this->mysql->close();
}
}
Dann funktioniert es. Warum brauche ich aber "this"? es gibt in der Klasse weit und breit keine lokale Variable, die mysql heißt. normalerweise müsste ich doch auch nur "mysql" schreiben dürfen.
Muss ich in PHP etwa Eigenschaften immer mit "this" ansprechen?
|

03-08-2008, 20:23
|
|
PHP-Desaster
PHP Expert
|
|
Registriert seit: Mar 2006
Beiträge: 3.104
|
|
Zitat:
|
Muss ich in PHP etwa Eigenschaften immer mit "this" ansprechen?
|
Jep, so ist es!
|

04-08-2008, 15:35
|
|
INC.
Registrierter Benutzer
|
|
Registriert seit: Nov 2005
Beiträge: 106
|
|
Okay, danke
Bleibt noch eine letzte Frage: ich habe eine private "validate_input" Methode, die die übergebenen Parameter mittels Regex auf Richtigkeit prüft. Sind die Parameter falsch, so soll abgebrochen werden.
Normalerweise fällt einem als erstes sowas ein (Pesudocode):
if(param == falsch) die("fehlermeldung");
Allerdings: Wird bei die() der Destructor überhaupt noch ausgeführt? Denn die Datenbank, von der wir es oben hatten, soll ja noch geschlossen werden. Abgesehen davon ist mir die() eh zu hart, denn es wird ja dann auch alles außerhalb des Objekts beendet.
Ich dachte anschliessend, folgendes wäre eine gute Lösung:
if(param==falsch) echo "Fehlermeldung";
unset($this);
Jedoch lese ich gerade auf php.net:
Zitat:
|
Hinweis: Es ist ab PHP 5 nicht mehr möglich, $this innerhalb einer Objektmethode zu löschen.
|
Wie würdet ihr das ganze lösen?
@Kropff: aka Peter Kropff? Ist ja lustig, ich lese unabhängig von dem Forum hier schon seit ein paar Tagen auf peterkropff.de, bin mit Google draufgestoßen. Schönes Ding! 
Falls du es auch als sinnvoll erachtest, könntest du ja bei der kurzen Erklärung von "this" auf deiner Seite ja noch erwähnen, dass man das Schlüsselwort bei PHP immer braucht (siehe Problematik oben). Imho ist das für Umsteiger von anderen Sprachen sonst erstmal verwirrend.
edit: wäre das eine gute Lösung? validate_input gibt einfach true oder false zurück. Die aufrufende Stelle macht bei false einfach garnix, das Objekt "läuft aus". kommt ja einem Abbruch ziemlic nahe.
Geändert von INC. (04-08-2008 um 15:40 Uhr)
|

04-08-2008, 15:40
|
jahlives
Master  
|
|
Registriert seit: Jun 2004
Ort: Hooker in Kernel
Beiträge: 8.283
|
|
Zitat:
|
Wie würdet ihr das ganze lösen?
|
Exception mit der Meldung rauswerfen. Und in der aufrufenden Datei mittels try...catch-Block abfangen und entsprechend reagieren. imho wird der Destruktor nach die() nicht mehr ausgeführt. Wenn es aber nur um das Schliessen der Verbindung geht, dann wird das am Ende des Scripts so oder so von selber erledigt.
|

04-08-2008, 18:22
|
|
INC.
Registrierter Benutzer
|
|
Registriert seit: Nov 2005
Beiträge: 106
|
|
Jop, daran hab ich auch gedacht, aber ich hätte gleich das ganze Beispiel zeigen sollen.. wie ihr sagt, wird ja nur innerhalb der Methode abgebrochen, nicht das ganze Objekt beendet.
PHP-Code:
public function __construct($host, $user, $pass, $database)
{
try {
@$this->mysql = new mysqli($host, $user, $pass, $database);
if (mysqli_connect_errno()) {
throw new Exception("Error ". mysqli_connect_errno(). ": ".mysqli_connect_error());
}
}
catch (Exception $e) {
echo $e->getMessage();
}
}
Das ist also der Konstruktor. Funktioniert soweit gut, NUR: die mysql-Eigenschaft wird immer vom Typ mysqli sein, auch wenn die 4 Zugangsparameter falsch sind und keine Verbindung hergestellt werden konnte. Dann erhält man ein defektes mysqli-Objekt.
Die anderen Methoden der Klasse werden evt. trotzdem ausgeführt und wollen mysql benutzen, auch wenn es defekt ist -> crash. Deshalb hab ich nach einer die() Alternative vesucht.. wenn mysql defekt ist, bringt die ganze Klasse nichts.
Bevor die Exception geworfen wird, könnte ich noch ein unset(this->mysql) einfügen und dann in allen Methoden erst prüfen, ob mysql noch existiert. Allerdings wirft PHP dann eine Notice, dass die Eigenschaft hopps gegangen ist.
Oder habt ihr das mit den Exceptions anders gemeint?
//edit: oje...ich könnte ja auch einfach nur statt unset($this->mysql) zu schreiben $this->mysql = "" setzen. Wäre es dann "resettet" und vom mysqli-Objekt befreit? Oder gibts fürs Zurücksetzen gar eigene Funktionen?
Geändert von INC. (04-08-2008 um 18:25 Uhr)
|

04-08-2008, 18:41
|
|
3DMax
PHP Senior
|
|
Registriert seit: Jan 2004
Beiträge: 1.916
|
|
macht irgendwie wenig sinn:
exception werfen, fangen und ausgeben alles innerhalb einer methode.
dann kannst du es auch gleich so schreiben:
PHP-Code:
if(!bedingung)
{
echo 'fehler';
}
also throw new Exception ... ist ok
der try-catch-block gehört irgendwo außerhalb hin.
|

04-08-2008, 23:47
|
|
INC.
Registrierter Benutzer
|
|
Registriert seit: Nov 2005
Beiträge: 106
|
|
Ja da hast du recht, habs geändert. Die Probleme haben sich übrigens in Luft aufgelöst, und ja, $var = "" scheint die Vairable wirklich zu resetten bzw. das Objekt von ihr zu entfernen.
Das einzige was mich noch plagt, ist aus einem mysqli-Objekt herauszuquetschen, mit welcher Datenbank es verbunden ist... scheint aber keine nützliche Eigenschaft zu haben, die einem das sagt.
Danke nochmal
Geändert von INC. (04-08-2008 um 23:50 Uhr)
|

05-08-2008, 00:39
|
|
PHP-Desaster
PHP Expert
|
|
Registriert seit: Mar 2006
Beiträge: 3.104
|
|
Zitat:
|
Das einzige was mich noch plagt, ist aus einem mysqli-Objekt herauszuquetschen, mit welcher Datenbank es verbunden ist... scheint aber keine nützliche Eigenschaft zu haben, die einem das sagt.
|
Da scheint es keine direkte Methode für zu geben, ist aber auch i.d.R. nicht notwendig. Aber du kannst ja beim Erstellen des Objektes den entsprechenden Wert als Klassenmember mitspeichern.
|
|
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
|
|
|
| Themen-Optionen |
|
|
| Thema bewerten |
|
|
Forumregeln
|
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.
HTML-Code ist aus.
|
|
|
|
PHP News
|