PHP dynamisch mit unterschiedlichen Datenbanken verbinden?
Hallo!
Folgende Situation:
Es gibt mehrere Datenbanken. Eine für alle Installationen meines Projektes (beinhaltet Zugangsdaten für Schul-DB's) und dann weitere, schulspezifische Datenbanken, in denen jeweils andere Dinge stehen (wie zum Beispiel Schüler mit ihren Logindaten, etc.)
Der Benutzer ruft also eine Loginseite auf und gibt eine Schul-ID ein. Nach Buttonklick wird die an ein PHP-Skript übergeben, welche dann aus der Datenbank aller Instanzen die entsprechenden Zugangsdaten für die schulspezifische Datenbank ausliest (anhand der Schul-ID).
Anschließend sollen diese als Variable gesetzt werden, sodass von überall in diesem Skript darauf zugegriffen werden kann. Dabei soll das Ganze allerdings nur für diese Session ersetzt werden und nicht in der Datei. Sodass andere Schüler andere Schul-ID's und damit auch andere Schul-DB's verwenden können.
Wenn der Benutzer dann auf der Loginseite seinen Benutzernamen und sein Passwort eingibt, wird dieses wieder an das PHP-Skript übergeben, welches nun in der schulspezifischen DB nachschaut, ob dort der entsprechende Nutzer existiert.
Folgendes Schema habe ich bis jetzt:
class DB {
private static $_api_username = "root";
private static $_api_password = "";
private static $_api_host = "localhost";
private static $_api_name = "programmingnow_host";
private static $_api;
private static $_db_username = $_SESSION['school_db_user'];
private static $_db_password = $_SESSION['school_db_pass'];
private static $_db_host = "localhost";
private static $_db_name = $_SESSION['school_db_name'];
private static $_db;
function __construct() {
try {
self::$_api = new PDO("mysql:host=" . self::$_api_host . ";dbname=" . self::$_api_name . ";charset=utf8mb4", self::$_api_username , self::$_api_password);
if (isset($_SESSION['school_db_name'])) {
self::$_db = new PDO("mysql:host=" . self::$_db_host . ";dbname=" . self::$_db_name . ";charset=utf8mb4", self::$_db_username , self::$_db_password);
}
}
catch(PDOException $e) {
echo "Datenbankverbindung gescheitert!";
die();
}
}
function connectToSchoolDB($school_id) {
$stmt = self::$_api->prepare("SELECT instance_db_name, instance_db_user, instance_db_pass FROM instances WHERE instance_key=:instance_key");
$stmt->bindParam(":instance_key", $school_id);
$stmt->execute();
$result = $stmt->fetch();
$result['instance_db_name'] = $_SESSION['school_db_name'];
$result['instance_db_user'] = $_SESSION['school_db_user'];
$result['instance_db_pass'] = $_SESSION['school_db_pass'];
}
[..] // Der ganze Rest an Funktionen (wie Login)
}
Der obige Code funktioniert aber nicht.
Könnt ihr mir da helfen? Wie kann ich das realisieren bzw. wo liegt der Fehler?
Danke schon einmal im Voraus!
VG!
Was funktioniert nicht? Rufst du überall session_start() auf ?
Jo. Ich bekomme immer den Fehler das der Wert bei den private static variablen ein fertiger String sein muss in "" sein muss, keine PHP $_SESSION Angabe...
Initialisiere die Variablen eben im Konstructor mit den Session-Inhalten.. ob das aus logischer Sicht mit den static eine gute Idee ist mag ich aus dem Stück Code nicht beurteilen.
Okay, danke!
1 Antwort
Ich habe gerade sehr viele Fragezeichen über meinem Kopf, da ich nicht wirklich verstanden habe was du eigentlich erreichen möchtest.
Ich glaube du weißt noch nicht so genau, was du eigentlich tust und was du vor hast. (Das soll aber um Gottes willen kein Vorwurf sein - jeder hat mal klein angefangen! Und wenn ich heute meine Codes von damals sehen würde .... 🙈)
Authentifizierungsinformationen (Benutzername, Kenntwort, ... etc) sollten nirgendwo im Klartext persistiert sein. Und diese Daten brauchst du auch eigentlich nur 1x bei der Authentifizierung, danach nicht mehr. Dementsprechend gibt es auch keinen Grund sie irgendwo in einer Session abzulegen.
Du hast bereits einen Fehler in deinem Konzept und der wird deine komplette weitere Entwicklung komplizierter machen als sie letztlich sein müsste.
Würde es funktionieren die entsprechenden Daten in einer Datei zu speichern? Nach der Struktur:
{
"db_name": "PLACEHOLDER",
"db_user": "PLACEHOLDER",
"db_pass": "PLACEHOLDER",
"school_id":"PLACEHOLDER"
}
Aber wie würde ich dann weiter machen?
Ich hatte auch zuerst den Gedanken, ein Einheitliches PW und Username für alle Schul-DB's zu machen und dann nur die Schul-ID's dynamisch zu ersetzen - hatte das aber für zu unsicher befunden...
Die Größe ist nie ein Grund für mehrere Datenbanken, es macht auch keinen Unterschied da sie nach wie vor auf der gleichen physischen Server (=localhost) gespeichert sind. Ich habe Datenbanken mit mehreren Hundert Millionen Zeilen betrieben (auch unter MySQL) und das ohne Probleme und sehr effizient. Das könntest du dir also sparen. Und auch wenn du mehrere Datenbanken hättest, könntest du dem selben Datenbank Benutzer den Zugriff auf ebendiese gestatten. Deine Tabellenstruktur muss dann dementsprechend Designed werden um Mandantenfähig zu sein.
Jegliche Art von Zugangsdaten die an das System übergeben werden müssen und nicht vom Benutzer übermittelt werden, sollten via Environment Variablen übergeben werden und von dort ausgelesen.
Umgebungsvariablen - diese werden z.B. vom Betriebssystem bereitgestellt.
https://de.wikipedia.org/wiki/Umgebungsvariable
Dann gleich noch eine andere Sache... Die Schüler sind in der Lage dann Dateien zu bearbeiten. In 6 unterschiedlichen Programmiersprachen. Dazu wird zuerst ein DB Eintrag und anschließend eine Datei in dem Ordner des Benutzers / der Klasse erstellt. Nun gibt es 6 unterschiedliche Editoren, für die unterschiedlichen Programmiersprachen. Dann kann ich auch, wenn ich eine HTML Datei damit erstelle, auf eine andere Verlinken. (<a> Tag) Nun möchte ich das alles aber auf eine DB umstellen. Problem: Wie verlinke ich jetzt per <a> Tag auf eine andere Seite, wenn doch der Code dieser Seite in einer Datenbank liegt?
Wordpress macht das ja auch irgendwie so. Und die Verlinkungen stehen...
Könntest du mir da weiterhelfen? Bei Fragen melde dich gern :)
du brauchst eine eindeutige Identifizierung für den Datenbankeintrag. In der Regel hast du in jeder Tabelle die du anlegst einen Primärschlüssel, welcher im einfachsten Fall ein Autoincrement integer ist und daher automatisch hochzählt für jeden Eintrag. Damit lässt sich jede Zeile einer Tabelle eindeutig identifizieren. Diesen Wert kannst du dann z.B. einfach als GET Parameter übergeben und bevor du ihn verwendest Validieren!
Alsooo, ich versuche es nochmal anders zu beschreiben. Der Schüler gibt eine Schul-ID an. Nun soll es für jede Schule eine eigene Datenbank geben, da es eine viel zu große DB wäre, alle Schüler / andere Inhalte der DB in EINER zu speichern - deswegen eine DB für eine Schule. Nun soll sich das Script mit der Datenbank verbinden, die zu dieser Schul-ID gehört. In dieser sollen dann alle weitere Vorgänge und Datenbankabfragen ablaufen. Alle Datenbankabfragen sehen so aus:
das $_db wird ja eigentlich zuvor definiert. Jetzt ist die Frage wie ich das hinbekomme, das sich das Script eben nur mit dieser, zur Schul-ID gehörigen, DB verbindet und damit weiterarbeitet. Ebenso soll das ganze nur für eine Session gelten - andere Besucher der Webseite müssen also wieder eine Schul-ID angeben, usw.