ERLEDIGT
NEIN
NEIN
ANTWORTEN
7
7
ZUGRIFFE
958
958
EMPFEHLEN
-
23.05.10 15:13 #1Lunatic Tutorials.de Gastzugang
Hallo liebe tutorials.de Community,
eine Sache vorweg, ich habe bereits gegoogled aber keine zufriedenstellende Lösung gefunden.
Es geht um folgendes:
Ich habe eine User Klasse. Die hält verschiedene Methoden bereit, z.B. selectUser($id), getUserData($key) etc...
u.a habe ich allerdings auch noch eine MySQL Klasse für Dinge die eine MySQL Klasse eben braucht. Queries, Fetching etc...
In der index.php lade ich erstmal die benötigten Klassen und instanziere sie dann:
Soa, dass wäre das Debakel. Die selectUser Methode ruft eine Methode der mySQL Klasse auf. Die Instanz der MySQL Klasse ist in der User Klasse allerdings nicht gültig weshalb ich die "call to a member function" Fehlermeldung erhalte.PHP-Code:$mysql = new MySQL('localhost', 'user', 'pass', 'db');
$core = new Core();
$user = new User();
echo $user->selectUser(1);
Denkbare Möglichkeiten wären nun eben entweder die MySQL Klasse als Referenz zu übergeben, in jede Methode der Userklasse ein global $mysql; zu bomben oder die MySQL Klasse statisch zu machen. Darüber hinaus könnte ich die MySQL Klasse statisch machen. Allerdings misfallen mir aber alle o.g. Möglichkeiten und von ein paaren habe ich auch schon mitgekriegt, sie seien unsauber.
Meine Frage wäre nun, wie sähe denn eine saubere Möglichkeit aus die MySQL Klasse in der User- und ggf. noch anderen Klassen verfügbar zu machen?
Ich danke schonmal im Voraus,
Lunatic
-
23.05.10 18:04 #2
- Registriert seit
- May 2006
- Ort
- There is no place like 127.0.0.1
- Beiträge
- 3.521
Du findest Singletons unsauber? Ich würde es darüber erledigen. Ist ganz einfach zu implementieren und beschleunigt wahrscheinlich sogar deinen Code etwas. Du brauchst deine Klasse MySQL noch nicht mal anpassen. Du abstrahierst sie einfach:
Code php:1 2 3 4 5 6 7 8 9 10 11 12 13
class Database extends MySQL { private static $_instance; public static function getInstance() { if( self::$_instance == null ) { self::$_instance = new Database('localhost', 'user', 'pass', 'db'); } return self::$_instance; } }
Jetzt fragst du dich vielleicht, warum das deinen Code beschleunigen soll. Weil du immer nur eine Instance von MySQL (bzw. Database) hast. Das ganze verwendest du dann so:
Code php:1 2 3 4
$user = Database::getInstance()->query("SELECT * FROM users WHERE id = " . $userid); $userdetails = Database::getInstance()->query("SELECT * FROM userdetails WHERE userdetailid = " . $user->detailid); // usw. usf.
Was daran unsauber sein soll, verstehe ich noch nicht ganz. Es gibt zwar eine Methode, bei der bewiesen werden kann, das ein Singleton nicht immer ein Singleton ist, aber das ist bei PHP so gut wie unmöglich anzuwenden, da PHP in sich nicht threaded ist. Wenn man aber auf Nummer sicher gehen will, implementiert man in ein Singleton auch noch Mutexes. Dann hat man prinzipiell gesehen sogar die Critical-Sections-Implementierung von Java implementiert.Grüße
--
Qualität des Codes wird in WTF's/Min gemessen: Je mehr, desto schlechter der Code ;-)
-
Kann mich Saftmeister nur anschließen. Das Singleton Pattern bietet sich insbesondere bei Datenbank Instanzen an.
Grüße BN
-
24.05.10 12:48 #4Lunatic Tutorials.de GastzugangWenn man die Verbindung zu nur einer Datenbank gleichzeitig herstellen will...Kann mich Saftmeister nur anschließen. Das Singleton Pattern bietet sich insbesondere bei Datenbank Instanzen an.
-
24.05.10 13:08 #5
- Registriert seit
- May 2006
- Ort
- There is no place like 127.0.0.1
- Beiträge
- 3.521
Grüße
--
Qualität des Codes wird in WTF's/Min gemessen: Je mehr, desto schlechter der Code ;-)
-
24.05.10 13:22 #6
Du könntest auch das globale Array $GLOBALS verwenden:
PHP-Code:$GLOBALS['DB'] = new MySQL('localhost', 'user', 'pass', 'db');
public function selectUser($id)
{
$GLOBALS['DB']->Query("...");
}
mfg ComFreek
Falls ich dir geholfen habe, würde ich mich über ein DANKE freuen!
Kenn mich am besten aus in C++, WEB-Sprachen (PHP, HTML, JavaScript) und vllt. mehr
[PHP] Überprüfen, ob Website erreichbar • Sicherheit in PHP-Codes schaffen • Google Chrome-Extension für tutorials.de • json_compress()
-
Wie wäres es den mit dem Registry-Pattern: Registry
In deiner index.php oder in deinem Core, wo die Datenbankverbdindung aufbaust setzt du sie in die Registry. Nun kannst du in jeder Datei wo du eine Verbindung brauchst sie abfragen.
So etwa:
Code PHP:1 2 3 4 5 6 7 8
try { $db = new PDO($dsn, $user, $password, $attributes); } catch(PDOException $e) { echo "An exception occured while trying to connect to Database. Error: ".$e->getMessage(); } // Datenbank registrieren Registry::set('db', $db);
Und dann in den Dateien/Klassen wo du sie brauchst:
Code PHP:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
class Model { private static $db = null; public static function getDB() { self::$db = Registry::get('db'); return self::$db; } public static function getUser($id) { $stmt = self::getDB()->prepare("SELECT * FROM user WHERE ID=:id"); $stmt->bindParam(':id', $id); $stmt->execute(); return $stmt->fetch(); } }
Das wars!
-
sagt wer?
Konfigurations-Klasse (kannste auch anders und ohne Klasse machen, ich möchte es nur andeuten):
angedeutete Datenbank-Klasse (Singleton auch für mehrere Connections):PHP-Code:class DbConfig
{
/**
* KonfigurationsArray
* @var array $dbConfigs
*/
private static $dbConfigs = array (
'db0' => array (
'user' => 'root',
'pass' => '',
'host' => 'localhost',
'port' => 3306,
'dba' => 'database1'
),
'db1' => array (
'user' => 'root',
'pass' => '',
'host' => 'andererhost',
'port' => 3306,
'dba' => 'database39'
)
);
/**
* Getter
* @param string $instanceName
* @return array
*/
public static function get ($instanceName)
{
if (!isset (self::$dbConfigs [$instanceName]))
{
// Exception werfen oder andere Fehlerbehandlung...
}
return self::$dbConfigs [$instanceName];
}
}
kleiner Test:PHP-Code:class MyDatabase
{
/**
* Intanzholder
* @var array
*/
private static $instances = array ();
/**
* Getter für Datenbankinstanz
* @param string $instanceName
* @return MyDatabase
*/
public static function getInstance ($instanceName)
{
if (!isset (self::$instances [$instanceName]))
{
self::$instances [$instanceName] = new MyDatabase ($instanceName);
}
return self::$instances [$instanceName];
}
/**
* Konstruktor
* nicht public aufrufbar, da nur über getInstance instanzierbar
* @param string $instanceName
*/
private function __construct ($instanceName)
{
$this->connect (DbConfig::get ($instanceName));
}
/**
* Verbindungsaufbau
* @param array Verbindungsparameter
*/
private function connect ($dbConfig)
{
// mysql connection ...
print_r ($dbConfig);
}
}
Du bekommst lediglich 2x die Parameter gepromptet. Der Code ist so nicht zu verwenden, da Exceptions/Fehlerbehandlungen fehlen und auch sonst nützliche Dinge. Aber das erklärt sich von selbst. Dein Argument "geht nicht" zählt also nicht. Mit GLOBAL-Gedöns würde ich gleich mal gar nicht arbeiten. Das ist zwar schön einfach aber auch schön hässlich.PHP-Code:MyDatabase::getInstance ('db0');
MyDatabase::getInstance ('db0');
MyDatabase::getInstance ('db0');
MyDatabase::getInstance ('db1');
MyDatabase::getInstance ('db0');
MyDatabase::getInstance ('db1');
MyDatabase::getInstance ('db0');
Grüße BN
Ähnliche Themen
-
Innerhalb einer Klasse eine Instanz einer anderen Klasse
Von HackerNeo im Forum VisualStudio & MFCAntworten: 1Letzter Beitrag: 17.11.09, 13:08 -
Instanz einer Klasse über deren Namen erzeugen
Von Marcel G im Forum PHPAntworten: 3Letzter Beitrag: 18.12.07, 15:38 -
Instanz einer Klasse mit dynamischen Namen und Singleton-Pattern
Von daddz im Forum PHPAntworten: 2Letzter Beitrag: 30.03.06, 20:40 -
Variable aus CMainFrame in anderer Klasse verwenden
Von PascalRode im Forum VisualStudio & MFCAntworten: 5Letzter Beitrag: 19.08.04, 01:17 -
sql handle als instanz einer klasse per konstruktor
Von Transmitter im Forum PHPAntworten: 4Letzter Beitrag: 28.10.02, 00:47





Zitieren



Login






[PHP][Snippet] Array zu XML konvertieren