De temps en temps, je vois des questions concernant la connexion à la base de données.
La plupart des réponses ne sont pas comme je le fais, ou je pourrais simplement ne pas obtenir les réponses correctement. En tous cas; Je n'y ai jamais pensé parce que ma façon de faire fonctionne pour moi.
Mais voici une pensée folle; Peut-être que je fais tout cela mal, et si c'est le cas; J'aimerais vraiment savoir comment me connecter correctement à une base de données MySQL en utilisant PHP et PDO et la rendre facilement accessible.
Voici comment je fais:
Tout d'abord, voici ma structure de fichiers (dépouillée) :
public_html/
* index.php
* initialize/
-- load.initialize.php
-- configure.php
-- sessions.php
index.php
Tout en haut, j'ai 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');
Je sais qu'il existe une meilleure façon, ou plus correcte, d'inclure des cours, mais je ne me souviens pas de ce que c'était. Je n'ai pas encore eu le temps de l'examiner, mais je pense que c'était quelque chose avec autoload
. quelque chose comme ca...
configure.php
Ici, je remplace simplement certaines propriétés de php.ini et fais une autre configuration globale pour le site
connect.php
J'ai mis la connexion sur une classe pour que d'autres classes puissent étendre celle-ci ...
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();
//
Ici, je pense qu'il y a place pour une amélioration massive depuis que j'ai récemment commencé à apprendre la POO et à utiliser PDO au lieu de mysql.
Je viens donc de suivre quelques tutoriels pour débutants et d'essayer différentes choses ...
sessions.php
En plus de gérer les sessions régulières, j'initialise également certaines classes dans une session comme celle-ci:
if (!isset($_SESSION['sqlQuery'])){
session_start();
$_SESSION['sqlQuery'] = new sqlQuery();
}
De cette façon, cette classe est disponible partout. Ce n'est peut-être pas une bonne pratique (?) ...
Bref, c'est ce que cette approche me permet de faire de partout:
echo $_SESSION['sqlQuery']->getAreaName('county',9); // outputs: Aust-Agder (the county name with that id in the database)
À l'intérieur de ma sqlQuery
- classe , que extends
ma connect_pdo
- classe , j'ai une fonction publique appelée getAreaName
qui gère la demande à ma base de données.
Assez chouette je pense.
Fonctionne comme un charme
Alors c'est comme ça que je le fais.
De plus, chaque fois que j'ai besoin de récupérer quelque chose de ma base de données hors d'une classe, je fais simplement quelque chose de similaire à ceci:
$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);
Depuis que j'ai mis la connexion dans une variable à l'intérieur de connect_pdo.php , je viens d'y faire référence et je suis prêt à partir. Ça marche. J'obtiens mes résultats attendus ...
Mais indépendamment de cela; J'apprécierais vraiment que vous me disiez si je suis loin d'ici. Ce que je devrais faire à la place, les domaines que je pourrais ou devrais changer pour amélioration, etc.
J'ai hâte d'apprendre ...
Réponses:
Le but
Selon moi, votre objectif dans ce cas est double:
Solution
Je recommanderais d'utiliser à la fois la fonction anonyme et le modèle d'usine pour gérer la connexion PDO. Son utilisation ressemblerait à ceci:
Puis dans un fichier différent ou inférieur dans le même fichier:
L'usine elle-même devrait ressembler à ceci:
De cette façon, vous auriez une structure centralisée, qui garantit que la connexion n'est créée que lorsque cela est nécessaire. Cela faciliterait également le processus de test unitaire et de maintenance.
Le fournisseur dans ce cas se trouverait quelque part au stade du bootstrap. Cette approche donnerait également un emplacement clair où définir la configuration que vous utilisez pour vous connecter à la base de données.
Gardez à l'esprit qu'il s'agit d'un exemple extrêmement simplifié . Vous pourriez également bénéficier de regarder deux vidéos suivantes:
Aussi, je recommanderais fortement de lire un tutoriel approprié sur l'utilisation de PDO (il existe un journal de mauvais tutoriel en ligne).
la source
mysql_*
vers PDO. Ensuite, vous pouvez revenir et regarder ces solutions, qui s'adressent à ceux qui utilisent déjà PDO, mais qui ont besoin d'un moyen de partager la connexion DB entre plusieurs classes.Je suggérerais de ne pas utiliser
$_SESSION
pour accéder à votre connexion DB globalement.Vous pouvez faire l'une des choses suivantes (de la pire aux meilleures pratiques):
$dbh
utilisant l'global $dbh
intérieur de vos fonctions et classesUtilisez un registre singleton et accédez-y globalement, comme ceci:
Injectez le gestionnaire de base de données dans les classes qui en ont besoin, comme ceci:
Je recommande vivement le dernier. C'est ce qu'on appelle l'injection de dépendances (DI), l'inversion de contrôle (IoC) ou simplement le principe hollywoodien (ne nous appelez pas, nous vous appellerons).
Cependant, il est un peu plus avancé et nécessite plus de "câblage" sans cadre. Donc, si l'injection de dépendances est trop compliquée pour vous, utilisez un registre singleton au lieu d'un tas de variables globales.
la source
sqlQuery
-class en session puisqu'elle s'étendconnect_pdo
?Je suis récemment venu à une réponse / question similaire par moi-même. Voici ce que j'ai fait, au cas où quelqu'un serait intéressé:
Pour l'appeler, il vous suffit de modifier cette ligne:
Et l'indication de type si vous l'utilisez pour (\ Library \ PDO $ DB).
C'est vraiment similaire à la fois à la réponse acceptée et à la vôtre; cependant il a un avantage notable. Considérez ce code:
Bien qu'il puisse ressembler à un PDO normal (il ne change que par cela
\Library\
), il n'initialise en fait pas l'objet tant que vous n'appelez pas la première méthode, quelle qu'elle soit. Cela le rend plus optimisé, car la création d'objet PDO est légèrement coûteuse. C'est une classe transparente, ou ce qu'on appelle un Ghost , une forme de Lazy Loading . Vous pouvez traiter le $ DB comme une instance PDO normale, le faire circuler, effectuer les mêmes opérations, etc.la source
la source