Bonjour
Ayant suivi les cours de la POO de grafikart, je me retrouve devant une problématique.
Le MVC traditionnel, nous permet de nous conncecter à une seule base de donnée en même temps. Cependant , j'ai deux bases de données contenant chacune la table Posts par exemple. (L'une listant les articles anciens) et l'autre les nouveaux.
Comment puis je modificier la classe mysqlDatatases pour me connecter sur différente bases de données et ensuite l'intégrer dans mes vues.
Cordialement
Salut,
Il suffit de créer 2 instances : une pour ta première BDD et une pour ta seconde, tout simplement ;)
De plus, si je me rappelle bien, il s'agit de singletons donc réutilisable facilement à tout endroit de ton app.
Par contre, je trouve cela bizarre d'avoir deux bases de données.
Attention, si les deux bases sont sur le même serveur, inutile d'aller créer deux instances, une seule suffit pour se connecter. Il faut juste préciser dans ta query le nom de la base avant le nom de la table (ex. SELECT * FROM `ma_bdd`.`ma_table` WHERE `id` = 1;
).
Bonjour, et merci de vous portez à mon aide,
je vois ce que vous voulez dire, mais dans le pattern MVC de la formation, les fonctions "LoadModel" et "getTable" prennent en paramètre UNE connection à la base Mysql.
On va se tutoyer hein, on est pas chez les aristos ;)
A ce moment là, il te faut faire deux instances, une pour chaque DB.
Peux-tu me montrer le code de la méthode LoadModel
stp ?
Pour le tutoiement avec plaisir.. Merci
Le but de cette manoeuvre est de pouvoir travailler sur une vue avec l'appel à deux ou X base de données.
La méthode LoadModel est la suivante :
public function LoadModel($model_name){
$this->$model_name = Application::Instance()->getTable($model_name);
}
Bon, elle ne m'apprend rien ... je n'ai plus du tout la structure de son code en tête...
A quelle endroit se connecte-on à une base de données (la classe mysqlDatabases je suppose...) ? Peux-tu partager le bout de code correpondant s'il-te-plaît ?
Alors le fichier Config retourne un tableau avec toutes les informations concernant les serveurs mysql et j'ai étendu le probleme au cas ou à LDAP, mais je verrais cela plus tard
return [
'mysql' => [
'localhost' => [
'host' => 'localhost',
'database' => 'Mizzouland',
'username' => 'root',
'password' => 'root',
'charset' => 'utf8'
],
'maman' => [
'host' => 'plop',
'database' => 'plop',
'username' => 'plo3',
'password' => 'd',
'charset' => 'utf8'
]
],
'ldap' => [
]
];
ensuite la class Config est la suivante
namespace Kernel\Config;
class Conf{
private $settings = [];
private static $_instance;
public static function getInstance(){
if(is_null(self::$_instance)){
return self::$_instance = new Conf();
}
return self::$_instance;
}
public function __construct(){
$this->settings = require_once (__DIR__.DS.'Config.php');
}
public function get($key, $host){
return $this->settings[$key][$host];
}
public function getAll($key){
return $this->settings[$key];
}
ensuite la class mysql est la suivante
namespace Kernel\Database;
use \PDO;
use Kernel\Config\Conf;
class MysqlDatabase extends BaseDatabase{
private $testConfig;
private $testPdo;
private $serverChoice = 'localhost';
private $config;
public function __construct($server_name) {
$this->serverChoice = $server_name;
}
private function MysqlDB(){
$key = $this->serverChoice;
$this->testConfig = Conf::getInstance()->get('mysql', $key);
if($this->testPdo === NULL){
$pdo = new PDO ("mysql:dbname={$this->testConfig['database']};host={$this->testConfig['host']}", $this->testConfig['username'], $this->testConfig['password']);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->testPdo = $pdo;
}
return $this->testPdo;
}
la class application qui gere un peu tout
use Kernel\Database\MysqlDatabase;
use Kernel\Core\Main;
class Application{
public $dB;
protected static $title = 'DASHBOARD ';
public static $_instance;
/**
* SINGLETON QUI PERMET DE RECUPERER UNE SEULE ET MEME INSTANCE DE LA CLASS APPLICATION
* @return
*/
public static function Instance(){
if(is_null(self::$_instance)){
self::$_instance = new Application();
}
return self::$_instance;
}
/**
* UTILISATION DES FACTORY PERMETTANT D'INSTANCIER LA CLASSE QUE L'ON SOUHAITE
*/
public function getTable($name){
$class = '\\App\Tables\\'.ucfirst($name).'Table';
return new $class($this->getDB());
}
et pour terminer le baseController
namespace Kernel\Controller;
use Application;
class BaseController{
protected $viewPath;
protected $template;
protected $rendered = FALSE;
public function Render($view, $variables = []){
if($this->rendered){
$this->rendered = FALSE;
}
ob_start();
$view = str_replace('.', '/', $view).'.php';
extract($variables);
require $this->viewPath.DS.$view;
$Content_For_Layout = ob_get_clean();
if($this->template == 'Admin'){
$this->template = 'Admin'.DS.$this->template;
}
require ($this->viewPath.DS.'Layout'.DS.ucfirst($this->template).'.php');
$this->rendered = TRUE;
}
public function LoadModel($model_name){
$this->$model_name = Application::Instance()->getTable($model_name);
}
L'idée si elle est bonne est la suivante:
namespace App\Controller;
class PostsController extends AppController{
public function __construct() {
parent::__construct();
$this->LoadServer('localhost');
$this->LoadServer('TOTO');
$this->LoadModel('Post');
}
public function home(){
$post_1 = $this->localhost()->Post()->FindAll();
$post = $this->TOTO->Post->FindAll();
$this->Render('posts.home', compact('post', 'post_1'));
}
ENFIN ce serai mon ideal, à moins que vous ayez autre chose à me proposer.
MERCI
Où est le problème ? Lorsque tu instancies la classe MysqlDatabase
, tu choisis quelle DB tu veux taper non ? Donc tu peux créer 2 instances, une pour chaque BDD, non ?
j'ai oublie la fonction getDB dans la class Application
public function getDB(){
if($this->dB === NULL){
$this->dB = new MysqlDatabase();
}
return $this->dB;
}
le tuto nous fait instancier la classe MysqDatabase uniquement avec la fonction au dessus, et moi j'ai mis en paramètre
public function getDB($server_name){
if($this->dB === NULL){
$this->dB = new MysqlDatabase($server_name);
}
return $this->dB;
}
mais cela ne change pas le probleme, il faut que je change pas fonction loadModel en fonction de mysql(), mais je pensais que cela
Car si je rajoute un paramètre à la class LoadModel
public function LoadModel($model_name, $serveur){
$this->$model_name = Application::Instance()->getTable($model_name, $serveur);
}
il ne me creer pas deux instances, mais uniquement la premiere
C'est parceque il te faut un tableau d'instance et tu peux mettre en clef le nom de la connection et en valeur la connection elle-même
ensuite c'est du get($name) en fonction de ce que tu veux.
Je ne connais pas du tout ce terme.. de tableau d'instance. En gros cela veut dire que je stocke mes différentes instance pdo dans un tableau?