J'ai une question de savoir cela. Je voudrais commencer à réécrire un ancien code de fonction MySQL PDO. La façon dont il a été configuré est qu'un fichier externe contenant cette ligne (entre autres): qui créerait une connexion à ma base de données. Ceci est inclus au plus haut de mes pages et chargerait également toutes mes classes. Maintenant, si je souhaite créer une nouvelle connexion à l'aide de PDO, je ferais ce qui suit: p> Cependant, je ne peux pas avoir cette ligne de code sur un fichier séparé et appeler PDO À partir d'une classe comme suit: P> require_once 'db.php';
class info
{
protected $ID;
protected $pdo;
public function __construct($id)
{
$this->ID = $id; //
$this->pdo = new PDO('mysql:host='.SERVER.';dbname='.DB.';charset=utf8',USER, PASSWORD);
}
public function getName()
{
$query = "SELECT * FROM job";
$q = $this->pdo->query($query);
$data = $q->fetch(PDO::FETCH_ASSOC);
// do something
}
}
3 Réponses :
Lors de la création d'une connexion à une base de données, vous devez le faire dans une classe Singleton. Vous ne voulez jamais ouvrir une connexion à une base de données. Par exemple: alors vous pouvez appeler la base de données PS: Je suis au courant que ce singleton n'est pas le fil sûr. J'essayais simplement de mettre en évidence le concept pour op. P> p> :: geInstance () code> méthode de n'importe où dans votre classe et que vous n'avez pas besoin de continuer à écrire Votre code de connexion. P>
C'est intéressant. Seriez-vous capable de créer un exemple de travail avec la mise en œuvre et comment l'utiliser? J'essaie juste de voir la photo complète ici ... La méthode d'agrégation allait créer des milliers de connexions si je devais organiser une instance dans une boucle ...
@Chris: Oui, mais n'oubliez pas que PDO est une classe, donc plutôt que d'avoir une classe d'emballage, vous pourriez aller à la place. Ce faisant, cela signifie que toutes les méthodes d'AOP seront héritées par la base de données code>, plutôt que d'ajouter des méthodes d'emballage à l'enfant.
@Dimitri, je pense que c'est probablement mieux si vous essayez de le mettre en œuvre vous-même et regardez également le commentaire de Halfer qui est très important!
Je vais lui donner un coup. Ce qui m'a confondu, c'est que j'ai complètement manqué le nouveau document PDO () code> et essayait de déterminer où le mettre. Je viendrai avec un exemple et publierai un code. Au lieu d'envelopper la classe PDO, je vais l'étendre.
Double -1: Les objets PHP en dehors des extensions sont le fil-coffre-fort par défaut, Singleton est un cauchemar à tester sous ce formulaire, afin de pouvoir éviter tout frais si vous envisagez d'utiliser cette classe de base de données comme étant plus qu'un PDO Stockage d'instance.
@ Sébasienenrenauld Si Singleton doit être évité, comment voudriez-vous y aller? L'ensemble de la question était de pouvoir appeler en PDO de toute classe. Je ne vois pas pourquoi quelqu'un utiliserait la classe de base de données comme un seul stockage d'instance.
@Dimitri L'alternative de TT-Recommandée par Anti-Singleton, les passionnés d'unités de test permettent de passer des paramètres autour. Vous devez donc transmettre une connexion en temps de construction ou à la méthode Getter. Franchement, je pense que la testabilité a frappé d'utiliser un singleton (et parfois même une variable globale - l'horreur!) Est assez insignifiant.
Établir une connexion dans votre constructeur, n'aurait-il pas un impact majeur? Si je pouvais instaurer ma classe d'emploi après avoir tiré 10 000 enregistrements, cela ne créerait-il pas 10 000 connexions inutiles? Ou sommes-nous tombés dans la même fosse?
@Dimitri pas établissement i> une connexion lors de la construction d'objets; En passant dans une connexion déjà établie i>, à la construction ou à la getter statique. Le test de l'unité est allégué par la plupart des fanatiques de test unitaires pour être beaucoup plus faciles lorsque vous déménagez les choses du contexte ambiant et demandez explicitement qu'elles soient transmises en tant que paramètres; Il vous permet probablement, lors de la construction d'un test d'unité pour SOMEMETHOD () code>, pour non seulement savoir Que i>
SOMEMETHOD () CODE> a besoin d'un seul coup d'œil, mais pour donner
SOMEMETHOD () CODE> Paramètres de test sans construire tout un contexte.
Ah bon? C'est 2013. Nous avons de plus gros poissons à frire que les singletons. Il s'agit essentiellement d'un axiome accepté que les singletons sont mauvais ... non seulement sont Méthodes statiques considérées comme nocives a >, mais Etat mondial et singletons sont fragiles A>, la sagesse dominante est donc singletons vs global Etat, choisissez Ni ...
Je ne pense pas que vous puissiez simplement nier catégoriquement la valeur de ces modèles de conception. Le seul argument que j'entends est que les singletons sont plus difficiles à tester. Et si j'ai mis dans le travail pour mettre en place un environnement de test? Cela dépend aussi de ce que vous écrivez. Alors quittez la haine. Il y a beaucoup de place pour les singletons et l'injection de dépendance.
@Aligangji: Ce n'est pas le seul argument, et ce n'est pas le seul inclus dans ces liens. Ex: Singletons Faites des interfaces qui mentent (vous ne pouvez pas faire confiance à l'interface pour vous indiquer ce que le code a besoin ou peut faire). C'est une action fantasmagorique à distance (qui est toujours mauvais). Il tue l'idempotence du code (qui est fortement liée à la qualité du code). Il réduit la flexibilité du code. Il augmente le couplage temporel et global (qui sont tous deux fortement liés à la qualité globale du code). Au lieu de cela, les motifs de composition sont fortement recommandés car ils ne souffrent aucun de ces problèmes ...
Je pense que l'utilisation de Singleton dépend de ses utilisations. Dans ce cas, il ne s'agit que d'un lieu de stockage pour ma connexion DB et rien de plus. Comme mentionné précédemment, PDO est une classe et peut être étendu. Le seul tirage majeur que je vois à redéfinir presque tout ce que j'ai écrit pour intégrer l'extension. Si tel est le cas, peut-être en raison de mon manque d'expérience, cela ne ferait-il pas de PDO Ma classe "Core"? Cela signifierait toujours que je devais passer des variables dans mon constructeur de classe. Peut-être que c'est là que le cas de Singleton entrerait en jeu ...
@,IRCMAXELL Je conviens que l'injection de dépendance est la meilleure pratique. Je pense juste que l'application de cette meilleure pratique est prise à une extrême. Je sais que vous obtenez des votes pour ceux-ci, mais à mon avis, nous n'avons pas besoin de bowvotes et de commentaires anti-singleton à chaque fois qu'un singleton apparaît. Il suffit de poster un anwser à l'aide d'une injection de dépendance et d'expliquer pourquoi c'est mieux.
Voici ma première tentative:
class database extends PDO { protected static $instance; protected function __construct(){} public static function getInstance() { if(empty(self::$instance)) { $db_info = array( "db_host" => SERVER, "db_port" => PORT, "db_user" => USER, "db_pass" => PASSWORD, "db_name" => DB); self::$instance = new Database("mysql:host=".$db_info['db_host'].';port='.$db_info['db_port'].';dbname='.$db_info['db_name'], $db_info['db_user'], $db_info['db_pass']); } return self::$instance; } } class info { protected $ID; protected $pdo; public function __construct($id) { $this->ID = $id; // $this->pdo = database::getInstance(); } public function getName() { $query = "SELECT * FROM job"; $q = $this->pdo->query($query); $data = $q->fetch(PDO::FETCH_ASSOC); // do something } }
Au lieu de créer la connexion de base de données à l'intérieur du constructeur, il vaut mieux en faire une dépendance:
// $db = new PDO('mysql:host='.SERVER.';dbname='.DB.';charset=utf8',USER, PASSWORD); $info = new info($db, '123'); echo $info->getName();
J'avais pensé à cela, mais cela signifierait que je devrais le faire pour tous mes cas ... c'était la raison pour laquelle j'avais créé la connexion de base de données dans mon constructeur.
@Dimitri Je ne sais pas si cela s'applique à vous, mais vous pouvez créer une super classe qui accepte à la fois DB et ID (protégé) dans le constructeur ... alors toutes vos classes s'étendent de cela.
@Dimitri En outre, je ne voyais pas comment créer la connexion de base de données à l'intérieur de chaque constructeur est moins de travail que de transmettre la connexion DB à chaque constructeur.
Hmm, c'est une idée réellement. Il faudrait être correctement coordonné. Peut-être que ma connexion de dB comme la hiérarchie et tout le reste suit ...
J'ai pensé à ce que j'ai écrit, ça ne fait aucune différence ... je devrais faire la même quantité de travail de toute façon.
@Dimitri cool. N'hésitez pas à me demander plus si vous n'êtes pas sûr. Bonne chance :)
+1 pour faire l'effort de réécrire vos fonctions MySQL_ *!
Dupliqué possible de Comment définir correctement la connexion PDO