php.de

Zurück   php.de > Webentwicklung > PHP Einsteiger > PHP Tipps 2009

 
 
LinkBack Themen-Optionen Thema bewerten
Alt 16.10.2009, 13:54  
Neuer Benutzer
 
Registriert seit: 16.10.2009
Beiträge: 2
PHP-Kenntnisse:
Anfänger
Xenon54 befindet sich auf einem aufstrebenden Ast
Standard [Erledigt] Von einem Objekt auf ein anders Objekt zugreifen

Ich arbeite hier gerade an einem Projekt und habe dort 2 Klassen, bzw. Objekte erstellt.
Zum einen gibt es die Klasse der Datenbank, die alles Datenbank relevante erledigt. Diese Klasse erstellt bei dem Aufruf mit einem Konstruktor eine Verbindnug zur Datenbank.

Als zweites gibt es die Benutzer-Klasse, diese handelt alle wichtigen Benutzereigenschaften, die benötigt werden.

Allerdings greift die Benutzer-Klasse auf das Objekt der Datenbank-Klasse zu, um sich benötigt Informationen zu beschaffen, da die entsprechende Funktion der Benutzer-Klasse jedoch keinen Zugriff darauf hat, kommt es zum Fehler.

Folgend kommen noch die relevanten Code ausschnitte:

Code:
$db = new Database ($db_name, $db_server, $db_user, $db_pass);
Erstellung des Datenbank-Objekts

Code:
class user {

	function __construct($email, $pass)
	{
		$db->query ("SELECT * FROM nutzer WHERE email = '$email'");
Klassendefinition der Benutzerklasse

Code:
$user = new user ( $_POST["email"], $_POST["password"]);
Erstellung des Benutzerobjekts

Verständlicherweise kommt es dann zu folgendem Fehler:
Zitat:
Notice: Undefined variable: db in C:\xampp\htdocs\tausch\inc\user.inc.php on line 29

Fatal error: Call to a member function query() on a non-object in C:\xampp\htdocs\tausch\inc\user.inc.php on line 29
Da GLOBAL $db; scheinbar nicht funktioniert, hab ich im Moment das Problem umschifft, in dem ich $db in ein $_GLOBALS-Array verfrachte und es in der Konstruktorfunktion der Benutzerklasse entsprechend wieder raushole, aber besonders glücklich bin ich damit nicht.

Irgendwie hab ich auch nicht das Gefühl, dass ich mit Vererbungen arbeiten müsste, da die Klassen ja eigentlich verschieden Sachen machen.

Danke schon mal im vorraus für entsprechende Hilfe.
Xenon54 ist offline  
Sponsor Mitteilung
PHP Code Flüsterer

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

Alt 16.10.2009, 14:03  
Moderator
 
Benutzerbild von Chriz
 
Registriert seit: 11.05.2008
Beiträge: 6.269
Chriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer Anblick
Standard

Du musst der User-Klasse das $db-Objekt eben übergeben:
PHP-Code:
<?php
$db 
= new Database ($db_name$db_server$db_user$db_pass);
$user = new user ($db$_POST["email"], $_POST["password"]);
?>
Chriz ist offline  
Alt 16.10.2009, 14:05  
Erfahrener Benutzer
 
Benutzerbild von Dark Guardian
 
Registriert seit: 10.10.2009
Beiträge: 2.637
PHP-Kenntnisse:
Fortgeschritten
Dark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekannt
Standard

Gibt mehrere Methoden.

1. $db als Parameter dem Konstruktor der User-Klasse mitgeben.
2. $db->query zu einer statischen Methode machen
3. globals $db, sofern das $db Objekt nicht innerhalb einer Funktion oder einer anderen Klasse aufgerufen wird
4. $db eine getInstance() methode verpassen und ein Singleton draus machen.
5. $user von $db erben lassen.

Edit: wieder zu langsam....
Dark Guardian ist offline  
Alt 16.10.2009, 14:14  
Neuer Benutzer
 
Registriert seit: 16.10.2009
Beiträge: 2
PHP-Kenntnisse:
Anfänger
Xenon54 befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von Chriz Beitrag anzeigen
Du musst der User-Klasse das $db-Objekt eben übergeben:
PHP-Code:
<?php
$db 
= new Database ($db_name$db_server$db_user$db_pass);
$user = new user ($db$_POST["email"], $_POST["password"]);
?>
Genau das war meine erste Idee und es kam exakt der gleiche Fehler, das war vor 3 Stunden. JETZT geht es aber, keine Ahnung warum. Danke für die Hilfe.

Zitat:
Zitat von Dark Guardian Beitrag anzeigen
3. globals $db, sofern das $db Objekt nicht innerhalb einer Funktion oder einer anderen Klasse aufgerufen wird
Jetzt weiß ich auch, warum es nicht funktioniert. $db wir in der Datenbanklasse als Ressourcen-Variable verwendet. Danke für die Hilfe.
Xenon54 ist offline  
Alt 16.10.2009, 14:21  
Moderator
 
Benutzerbild von Chriz
 
Registriert seit: 11.05.2008
Beiträge: 6.269
Chriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer Anblick
Standard

Zitat:
Zitat von Dark Guardian Beitrag anzeigen
2. $db->query zu einer statischen Methode machen
Eine Datenbank-Verbindung ist aber zustands-basiert.

Zitat:
Zitat von Dark Guardian Beitrag anzeigen
3. globals $db, sofern das $db Objekt nicht innerhalb einer Funktion oder einer anderen Klasse aufgerufen wird
Global niemals verwenden, es gibt Parameter!

Zitat:
Zitat von Dark Guardian Beitrag anzeigen
4. $db eine getInstance() methode verpassen und ein Singleton draus machen.
Klassen werden damit schlechter testbar.

Zitat:
Zitat von Dark Guardian Beitrag anzeigen
5. $user von $db erben lassen.
Nein, Komposition über Vererbung. Ein User ist keine Erweiterung einer Datenbank.

Eine weitere Möglichkeit wäre eben, dass der User garkeine DB-Verbindung bekommt, sondern stattdessen von außen mit Daten gefüttert wird:
PHP-Code:
<?php
$user 
= new User();
$user->setNickname($_POST["nickname"]);
$meinDatenbankDingsbums->saveUser($user);

$andererUser $meinDatenbankDingsbums->loadUser(5);
?>
Chriz ist offline  
Alt 16.10.2009, 14:41  
Erfahrener Benutzer
 
Benutzerbild von Dark Guardian
 
Registriert seit: 10.10.2009
Beiträge: 2.637
PHP-Kenntnisse:
Fortgeschritten
Dark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekannt
Standard

@Chriz
Ich bin mir dessen bewusst. Ich wollte dem TE nur ein paar Möglichkeiten nennen. Denn um von A auf B zugreifen zu können bietet PHP mehr als genug...

Was das Singleton angeht:

Zitat:
Zitat von Chriz Beitrag anzeigen
Klassen werden damit schlechter testbar.
Kann ich spontan nicht nachvollziehen. Wenn ggf. der letzte Query oder Result abgelegt werden und innerhalb einer Klasse die auf die DB zugreift sich der Zustand ändert (weil z.B. eine andere Klassenmethode aufgerufen wurde die ihrerseits die DB nutzt), mag das vielleicht nicht hinhauen.

Ich bin jedenfalls kein Freund davon alles in Parameter zu stopfen.
Dark Guardian ist offline  
Alt 16.10.2009, 14:49  
Moderator
 
Benutzerbild von Chriz
 
Registriert seit: 11.05.2008
Beiträge: 6.269
Chriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer Anblick
Standard

Zitat:
Zitat von Dark Guardian Beitrag anzeigen
Kann ich spontan nicht nachvollziehen. Wenn ggf. der letzte Query oder Result abgelegt werden und innerhalb einer Klasse die auf die DB zugreift sich der Zustand ändert (weil z.B. eine andere Klassenmethode aufgerufen wurde die ihrerseits die DB nutzt), mag das vielleicht nicht hinhauen.
getInstance() innerhalb einer Klasse aufzurufen ist wie global. Von außen ist das nicht ersichtlich. Das ist der erste Punkt. Der zweite Punkt ist, dass du bei Unit-Tests dann keinerlei Einfluß mehr darauf nehmen kannst, welche Instanz oder Klasse (z.B. der DB) verwendet wird:
PHP-Code:
<?php
class Abc {
  
// ..
  
public function __construct() {
    
$this->_db Database::getInstance(_DSN_MYSQL_1);
    
// oder
    
$this->_db Database::getInstance("databaseXy");
  }
}
?>
wie willst du jetzt erzwingen, dass eine Test-Datenbank verwendet wird? Deshalb ist es viel besser, das Objekt zu übergeben, am Besten per Interface, damit der Unit-Test nicht daran gebunden ist auch ein solches Objekt zu übergeben, sondern nur eins, das so ähnlich funktioniert, aber vielleicht viel einfacher (mit festen Rückgabewerten z.B.) implementiert ist.
Chriz ist offline  
Alt 16.10.2009, 15:38  
Erfahrener Benutzer
 
Benutzerbild von Dark Guardian
 
Registriert seit: 10.10.2009
Beiträge: 2.637
PHP-Kenntnisse:
Fortgeschritten
Dark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekannt
Standard

Zitat:
Zitat von Chriz Beitrag anzeigen
getInstance() innerhalb einer Klasse aufzurufen ist wie global. Von außen ist das nicht ersichtlich. Das ist der erste Punkt. Der zweite Punkt ist, dass du bei Unit-Tests dann keinerlei Einfluß mehr darauf nehmen kannst, welche Instanz oder Klasse (z.B. der DB) verwendet wird:
PHP-Code:
<?php
class Abc {
  
// ..
  
public function __construct() {
    
$this->_db Database::getInstance(_DSN_MYSQL_1);
    
// oder
    
$this->_db Database::getInstance("databaseXy");
  }
}
?>
wie willst du jetzt erzwingen, dass eine Test-Datenbank verwendet wird? Deshalb ist es viel besser, das Objekt zu übergeben, am Besten per Interface, damit der Unit-Test nicht daran gebunden ist auch ein solches Objekt zu übergeben, sondern nur eins, das so ähnlich funktioniert, aber vielleicht viel einfacher (mit festen Rückgabewerten z.B.) implementiert ist.
In deinem Beispiel lässt die Database Klasse mehrere Datenbanken zu und disqualifiziert sich somit schon als Singleton. Zumindest nach dem was ich als "Singleton" kennengelernt habe.

Im Falle einer Singleton Datenbankklasse die auch nur eine Datenbank abbildet (wovon ich hier einfach mal ausging) sollte es reichen den entsprechenden Konfigurationsparameter für die Datenbank zu ändern um die Testdatenbank zu erzwingen.
Dark Guardian ist offline  
Alt 16.10.2009, 15:41  
Erfahrener Benutzer
 
Registriert seit: 13.05.2009
Beiträge: 1.166
PHP-Kenntnisse:
Fortgeschritten
dennis81 befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von Dark Guardian Beitrag anzeigen
In deinem Beispiel lässt die Database Klasse mehrere Datenbanken zu und disqualifiziert sich somit schon als Singleton. Zumindest nach dem was ich als "Singleton" kennengelernt habe.
Wie lässt die Klasse das denn zu?

Zitat:
Zitat von Dark Guardian Beitrag anzeigen
Im Falle einer Singleton Datenbankklasse die auch nur eine Datenbank abbildet (wovon ich hier einfach mal ausging) sollte es reichen den entsprechenden Konfigurationsparameter für die Datenbank zu ändern um die Testdatenbank zu erzwingen.
Das geht auch in der von Chriz geposteten Klasse. _DSN_MYSQL_1 ändern und fertig.
dennis81 ist offline  
Alt 16.10.2009, 15:45  
Erfahrener Benutzer
 
Benutzerbild von Dark Guardian
 
Registriert seit: 10.10.2009
Beiträge: 2.637
PHP-Kenntnisse:
Fortgeschritten
Dark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekannt
Standard

Zitat:
Zitat von dennis81 Beitrag anzeigen
Wie lässt die Klasse das denn zu?


Das geht auch in der von Chriz geposteten Klasse. _DSN_MYSQL_1 ändern und fertig.
Wenn ich sein Beispiel richtig verstanden habe wollte er verdeutlichen das durch die Übergabe des Parameters an getInstance() verschiedene Datenbanken aufgerufen werden können womit es nicht mehr möglich wäre ohne eine Änderung der getInstance() Methode eine bestimmte Datenbank zu erzwingen.

Ansonsten würde das Beispiel in meinen Augen keinen Sinn ergeben.
Dark Guardian ist offline  
 


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
Zugriff auf complexType Rückgabe Objekt von SOAP Aufruf? kuschky PHP-Fortgeschrittene 3 24.06.2010 12:35
Objekt löschen via Methodenübergabe desselben nikosch Software-Design 19 01.06.2009 00:38
[Erledigt] Objekt an Konstruktor übergeben hawkeye78 PHP Tipps 2009 7 28.02.2009 19:01
Objekt im GET-Query wird nicht übertragen Ralpho PHP-Fortgeschrittene 10 05.05.2008 10:03
Objekt als ComboBox behandeln Nalincah PHP Tipps 2008 2 08.11.2007 03:52
auf unterobjekte von div zugreifen JS/DOM Crypi HTML, Usability und Barrierefreiheit 4 05.04.2007 16:27
Via PHP auf eine andere festplatte zugreifen? skytrance PHP Tipps 2006 6 05.05.2006 16:23
OOP Denkfehler, wie lösen gegenseitiges Zugreifen CC84 PHP Tipps 2006 17 29.03.2006 20:21
Zugriff auf verschachteltes Objekt aus Funktion FloMX PHP-Fortgeschrittene 10 28.03.2006 17:01
[Erledigt] PHP5 OOP Zugriff aus einem Objekt auf ein externes Objekt PHP Tipps 2006 5 28.01.2006 16:05
Objekt übergeben Fatal Error PHP Tipps 2007 5 28.12.2005 14:43
Objekt erstellen, und direkt darauf zugreifen I-Spy Datenbanken 2 26.11.2005 19:56
Rechte für user vergeben - auf externe Datenbank zugreifen PHP Tipps 2005-2 8 07.10.2005 13:59
kann sich ein Objekt selbst serialisieren? ajo_silent PHP Tipps 2005-2 24 27.06.2005 09:13
objekt und collection PHP Tipps 2004-2 2 17.11.2004 08:46

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
php zugriff auf methode anderes objekt, php auf objekt zugreifen, php zugriff auf objekte, php auf objekt in objekt zugreifen, von einem objekt auf anderes zugreifen php, php in klasse auf datenbank zugreifen, innerhalb eines objekts ein anderes php, php auf andere objekte zugreifen, php auf ein objekt zugreifen, php innerhalb eines objektes auf ein anderes zugreifen, php auf anderes objekt zugreifen, zugriff auf objekte php, von einem objekt auf anderes zugreifen, php objekt zugriff, php auf objekte zugreifen, php zugriff auf objekt, php auf objekt außerhalb zugreifen, objekt auf anderes objekt zugreifen, php objekte zugriff, error:call to a member function query() on a non-object in c:\\xampp\\htdocs\\

Alle Zeitangaben in WEZ +2. Es ist jetzt 20:00 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