Von Zeit zu Zeit sehe ich Fragen zur Verbindung mit der Datenbank.
Die meisten Antworten sind nicht so, wie ich es mache, oder ich bekomme die Antworten einfach nicht richtig. Wie auch immer; Ich habe nie darüber nachgedacht, weil die Art und Weise, wie ich es mache, für mich funktioniert.
Aber hier ist ein verrückter Gedanke; Vielleicht mache ich das alles falsch, und wenn das der Fall ist; Ich würde wirklich gerne wissen, wie man mit PHP und PDO eine Verbindung zu einer MySQL-Datenbank herstellt und diese leicht zugänglich macht.
So mache ich das:
Hier ist zunächst meine Dateistruktur (abgespeckte) :
public_html/
* index.php
* initialize/
-- load.initialize.php
-- configure.php
-- sessions.php
index.php
Ganz oben habe ich require('initialize/load.initialize.php');
.
load.initialize.php
# site configurations
require('configure.php');
# connect to database
require('root/somewhere/connect.php'); // this file is placed outside of public_html for better security.
# include classes
foreach (glob('assets/classes/*.class.php') as $class_filename){
include($class_filename);
}
# include functions
foreach (glob('assets/functions/*.func.php') as $func_filename){
include($func_filename);
}
# handle sessions
require('sessions.php');
Ich weiß, dass es eine bessere oder korrektere Möglichkeit gibt, Klassen einzuschließen, kann mich aber nicht erinnern, was es war. Ich habe noch nicht die Zeit bekommen, mich damit zu beschäftigen, aber ich denke, es war etwas mit autoload
. sowas in der Art...
configure.php
Hier überschreibe ich im Grunde nur einige php.ini- Eigenschaften und mache eine andere globale Konfiguration für die Site
connect.php
Ich habe die Verbindung zu einer Klasse hinzugefügt, damit andere Klassen diese erweitern können ...
class connect_pdo
{
protected $dbh;
public function __construct()
{
try {
$db_host = ' '; // hostname
$db_name = ' '; // databasename
$db_user = ' '; // username
$user_pw = ' '; // password
$con = new PDO('mysql:host='.$db_host.'; dbname='.$db_name, $db_user, $user_pw);
$con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$con->exec("SET CHARACTER SET utf8"); // return all sql requests as UTF-8
}
catch (PDOException $err) {
echo "harmless error message if the connection fails";
$err->getMessage() . "<br/>";
file_put_contents('PDOErrors.txt',$err, FILE_APPEND); // write some details to an error-log outside public_html
die(); // terminate connection
}
}
public function dbh()
{
return $this->dbh;
}
}
# put database handler into a var for easier access
$con = new connect_pdo();
$con = $con->dbh();
//
Hier glaube ich, dass es Raum für massive Verbesserungen gibt, seit ich vor kurzem angefangen habe, OOP zu lernen und PDO anstelle von MySQL zu verwenden.
Also habe ich gerade ein paar Anfänger-Tutorials befolgt und verschiedene Sachen ausprobiert ...
session.php
Neben der Behandlung regulärer Sitzungen initialisiere ich auch einige Klassen in einer Sitzung wie der folgenden:
if (!isset($_SESSION['sqlQuery'])){
session_start();
$_SESSION['sqlQuery'] = new sqlQuery();
}
Auf diese Weise ist diese Klasse überall verfügbar. Dies ist möglicherweise keine gute Praxis (?) ...
Wie auch immer, mit diesem Ansatz kann ich dies von überall aus tun:
echo $_SESSION['sqlQuery']->getAreaName('county',9); // outputs: Aust-Agder (the county name with that id in the database)
In meinem sqlQuery
- Klasse , die extends
meine connect_pdo
- Klasse , habe ich eine genannte öffentliche Funktion , getAreaName
die die Anfrage an meine Datenbank behandelt.
Ziemlich ordentlich finde ich.
Funktioniert wie ein Zauber
So mache ich es also im Grunde.
Wenn ich etwas aus meiner Datenbank abrufen muss, das nicht in einer Klasse enthalten ist, mache ich einfach etwas Ähnliches:
$id = 123;
$sql = 'SELECT whatever FROM MyTable WHERE id = :id';
$qry = $con->prepare($sql);
$qry -> bindParam(':id', $id, PDO::PARAM_INT);
$qry -> execute();
$get = $qry->fetch(PDO::FETCH_ASSOC);
Da ich die Verbindung in eine Variable in connect_pdo.php eingefügt habe , beziehe ich mich nur darauf und kann loslegen . Es klappt. Ich bekomme meine erwarteten Ergebnisse ...
Aber unabhängig davon; Ich würde mich sehr freuen, wenn ihr mir sagen könnt, ob ich hier weit weg bin. Was ich stattdessen tun sollte, Bereiche, die ich zur Verbesserung ändern könnte oder sollte usw.
Ich bin gespannt zu lernen ...
Antworten:
Das Ziel
Aus meiner Sicht haben Sie in diesem Fall zwei Ziele:
Lösung
Ich würde empfehlen, sowohl die anonyme Funktion als auch das Factory-Muster für die PDO-Verbindung zu verwenden. Die Verwendung würde so aussehen:
Dann in einer anderen Datei oder niedriger in derselben Datei:
Die Fabrik selbst sollte ungefähr so aussehen:
Auf diese Weise erhalten Sie eine zentralisierte Struktur, die sicherstellt, dass die Verbindung nur bei Bedarf hergestellt wird. Dies würde auch den Prozess des Unit-Tests und der Wartung erheblich vereinfachen.
Der Anbieter befindet sich in diesem Fall irgendwo in der Bootstrap-Phase. Dieser Ansatz würde auch einen klaren Ort angeben, an dem die Konfiguration definiert werden kann, die Sie für die Verbindung mit der Datenbank verwenden.
Beachten Sie, dass dies ein extrem vereinfachtes Beispiel ist . Sie können auch von zwei folgenden Videos profitieren:
Außerdem würde ich dringend empfehlen, ein geeignetes Tutorial über die Verwendung von PDO zu lesen (es gibt ein Protokoll mit schlechten Online-Tutorials).
quelle
mysql_*
PDO migrieren möchten . Dann können Sie sich diese Lösungen ansehen, die sich an diejenigen richten, die bereits PDO verwenden, aber eine Möglichkeit benötigen, die DB-Verbindung zwischen mehreren Klassen zu teilen.Ich würde vorschlagen, nicht
$_SESSION
für den globalen Zugriff auf Ihre DB-Verbindung zu verwenden.Sie können eines der folgenden Dinge tun (in der Reihenfolge der schlechtesten bis besten Praktiken):
$dbh
überglobal $dbh
innerhalb Ihrer Funktionen und KlassenVerwenden Sie eine Singleton-Registrierung und greifen Sie wie folgt global darauf zu:
Fügen Sie den Datenbankhandler wie folgt in die Klassen ein, die ihn benötigen:
Ich kann das letzte sehr empfehlen. Es ist bekannt als Abhängigkeitsinjektion (DI), Inversion der Kontrolle (IoC) oder einfach das Hollywood-Prinzip (Rufen Sie uns nicht an, wir rufen Sie an).
Es ist jedoch etwas fortgeschrittener und erfordert mehr "Verkabelung" ohne Rahmen. Wenn Ihnen die Abhängigkeitsinjektion zu kompliziert ist, verwenden Sie eine Singleton-Registrierung anstelle einer Reihe globaler Variablen.
quelle
sqlQuery
greife ich global auf meine Datenbankverbindung zu, wenn ich meine -class in session setze, da sie erweitert wirdconnect_pdo
?Ich bin kürzlich selbst zu einer ähnlichen Antwort / Frage gekommen. Dies ist, was ich getan habe, falls jemand interessiert ist:
Um es aufzurufen, müssen Sie nur diese Zeile ändern:
Und die Typhinweise, wenn Sie sie verwenden, um (\ Library \ PDO $ DB).
Es ist sowohl der akzeptierten als auch Ihrer Antwort sehr ähnlich. es hat jedoch einen bemerkenswerten Vorteil. Betrachten Sie diesen Code:
Es sieht zwar wie ein normales PDO aus (es ändert sich
\Library\
nur dadurch), initialisiert das Objekt jedoch erst, wenn Sie die erste Methode aufrufen, je nachdem, um welche es sich handelt. Dies macht es optimierter, da die Erstellung von PDO-Objekten etwas teuer ist. Es ist eine transparente Klasse oder ein sogenannter Ghost , eine Form des Lazy Loading . Sie können die $ DB als normale PDO-Instanz behandeln, sie weitergeben, dieselben Vorgänge ausführen usw.quelle
quelle