Compréhension et transformation en PDO avec Singleton

yukimura27 Messages postés 10 Date d'inscription mardi 13 avril 2010 Statut Membre Dernière intervention 21 février 2011 - 18 févr. 2011 à 18:01
yukimura27 Messages postés 10 Date d'inscription mardi 13 avril 2010 Statut Membre Dernière intervention 21 février 2011 - 21 févr. 2011 à 17:51
Bonjour à tous,


Voila j'ai un problème de compréhension, j'ai repris le code d'une de vos application.

J'aurai aimé que l'on m'explique clairement ce bout de code et surtout que l'on m'aide a le transformer en PDO car a chaque fois que j'ai utilisé un singleton + PDO, j'avais une erreur de type call query() ou prepare () on non objet et la tou marche pour le mieux.

D'ou mes questions :

Pourquoi ça marche ?

Explication lignes par lignes si possible ?

Transformation en PDO ?

Pour qu'elle raison utiliser une classe abstract dans dbfactory ?

Qu'elle est l'utilité de __autoload dans index.php, pourquoi ne pas mettre require_once direct ?

J’espère que quelqu'un aura la gentillesse et la patience de m'expliquer tout ça.

page mysql.php :

<?php
class mysql extends dbfactory {

protected $default_cfg = array(
'host' => 'localhost',
'user' => 'root',
'passwd' => '',
'name' => 'test');

// connection à la base
protected function connect () {
$this->_config['link'] = @mysql_connect($this->_config['host'], $this->_config['user'], $this->_config['passwd']);
if (!$this->_config['link'] ) {
throw new Exception('Erreur lors de la connection vers : '.$this->_config['host'].'.');
}

$this->_config['base'] = @mysql_select_db($this->_config['name'], $this->_config['link']);
if (!$this->_config['base'] ) {
throw new Exception('Erreur lors de l\'ouverture de la base de donnée : '.$this->_config['name'].'.');
unset($this->_config);
}
echo 'connection réussie avec '.__CLASS__;
echo '
';
}

// Fermeture de la base de données au moment de la destruction de la classe.
public function __destruct() {
mysql_close($this->_config['link']);
}

// création d'une requête
public function query ($sql, $desc=NULL) {
$this->query = @mysql_query ($sql, $this->_config['link'] );
if ($this->query) {
return $this->query;
} else {
throw new Exception (mysql_error() );
return false;
}

}

// récupère les résultats dans un tableau associatif
public function fetch_assoc ($query=NULL) {
if (isset($query)) {
$this->query = $query;
}
return mysql_fetch_assoc ($this->query);
}

}
?>

page dbfactory.php:

<?php
abstract class dbfactory {

private static $instance; // Instance courante de la classe

protected $_config; // Paramètres de configuration base de donnée.
protected $query; // Ressource de query
protected $bdd;

// Initialise les variables de connections et active la connection à la base de donnée.
// Constructeur protégé permettant de n'avoir qu'une unique instance de la classe grâce à la méthode singleton
protected function __construct ($host=NULL, $user=NULL, $passwd=NULL, $name=NULL) {
if (!is_array($this->default_cfg)) {
throw new Exception('Vous devez remplir les paramètres de la configuration par defaut de votre base de donnée');
}

foreach ($this->default_cfg as $key=>$val ) {
$this->_config[$key] = (isset($$key) ) ? $$key : $val;
}

unset ($this->default_cfg); // Enlève les paramètres par defaut pour éviter toute confusion possible.
$this->connect ();
}

// usinage : permet d'instancier la classe correcte en fonction de la db choisie
public static function factory ($type, $host=NULL, $user=NULL, $passwd=NULL, $name=NULL) {
if (class_exists ($type)) {
$className = $type;
return new $className ($host, $user, $passwd, $name);
} else {
throw new Exception ('Pas d\'implémentation disponible pour ' . $type);
}
}

// n'autorise qu'une seule instance de la classe
public static function singleton () {
if (!isset(self::$instance)) {
$c = __CLASS__;
self::$instance = new $c;
}
return self::$instance;
}

// on avertit le développeur qu'il n'a pas le droit de cloner l'objet instancié
public function __clone() {
trigger_error('Le clônage n\'est pas autorisé.', E_USER_ERROR);
}

// méthodes abstraites
abstract protected function connect();
abstract public function __destruct();
abstract public function query($sql, $desc=NULL);
abstract public function fetch_assoc($query=NULL);
/*
abstract public function num_rows($query=NULL);
abstract public function fetch_row($query=NULL);
abstract public function fetch_array($query=NULL);
abstract public function free();
*/
}
?>
et index.php basic ^^ :

<?php

// on utilise la fonction magique __autoload pour charger automatiquement tous les fichiers de classe lorsqu'un appel est demandé.
function __autoload($class_name) {
require_once ($_SERVER['DOCUMENT_ROOT'].'/CDMEF/CLASSES/'.$class_name . '.php');
}

try {
$db = dbfactory::factory ('mysql', 'localhost', 'root', '', 'cdmef');
} catch (Exception $e) {
die($e->getmessage());
}

$requete = $db->query ('SELECT COUNT(id_news) as nbNews FROM news');
$res = $db->fetch_assoc ($requete);
$nbNews = $res['nbNews'];
$nbPage = ceil($nbNews/4);

if(isset($_GET['p']) && $_GET['p']>0 && $_GET['p']<=$nbPage)
{
$cPage = $_GET['p'];
}
else
{
$cPage = 1;
}

$firstPage = ($cPage-1)*4;

$requete = $db->query ('SELECT * FROM news ORDER BY date_news DESC LIMIT '.$firstPage.',4');
while ($res = $db->fetch_assoc ($requete))
{
echo "{$res['titre_news']}";
echo "

";
echo "{$res['contenu_news']}";
echo "

";
}


for($i=1;$i<=$nbPage;$i++)
{
if($i==$cPage)
{
echo " $i /";
}
else
{
echo "$i /";
}

}



?>

Merci bien ^^.

3 réponses

yukimura27 Messages postés 10 Date d'inscription mardi 13 avril 2010 Statut Membre Dernière intervention 21 février 2011
18 févr. 2011 à 18:08
Rebonjour,

Je sais que j'en demande beaucoup mes j'aimerais avoir une compréhension parfaite avant de continuer sur cette voix PHP POD POO.

Et surtout ça fait 2 jours que je suis sur ça et je croix que je vais me tirer une balle si ça continue ^^ (je rigole bien sur).

Un très grand MERCI a celui qui aura la patience et le temps de me répondre et de m'expliquer .
0
phpAnonyme Messages postés 392 Date d'inscription mercredi 28 octobre 2009 Statut Membre Dernière intervention 23 mars 2012 55
19 févr. 2011 à 18:04
lut,

a chaque fois que j'ai utilisé un singleton + PDO, j'avais une erreur de type call query() ou prepare ()
Ben commence par lire ce qu'on te répond ou t'explique : http://www.phpcs.com/forum/sujet-PROBLEME-AVEC-REQUETES-PREPARE_1498845.aspx

Explication lignes par lignes si possible ?

Je ne pense pas que tu trouvera âme charitable pour faire ça !

Pour qu'elle raison utiliser une classe abstract dans dbfactory ?

- Ce n'est ni plus ni moins une classe normale sauf qu'on ne peut pas l'instancier directement
- Si tu veux l'utiliser tu sera obliger de l'étendre à une autre classe et de définir dans la classe fille les méthodes abstraites qui s'y trouve.

Qu'elle est l'utilité de __autoload dans index.php, pourquoi ne pas mettre require_once direct ?
Ben justement ça t'évite de mettre des require() à chaque fois que tu veux utiliser une classe.
__autoload() se chargera de le faire quand une classe quelconque sera appelé.





______________________________________________________________________
0
yukimura27 Messages postés 10 Date d'inscription mardi 13 avril 2010 Statut Membre Dernière intervention 21 février 2011
21 févr. 2011 à 17:51
Bonjour,

Depuis le temps j'ai réussi a faire tout ce que je demandais moi même ^^.
Pareille pour __autoload() mais merci d'avoir répondu.
J'aurais juste une question, on m'a dit d'utiliser $PDOinstance a la place de ma variable, pour qu'elle raison ???? et aussi j'utiliser une requête préparé pour afficher ma liste de news sans utiliser les Getters et Setters, qu'elle est l’intérêt de les utiliser est ce vraiment mieux ????

Je donne le code de mon singleton pour$PDOinstance:

<?php

class DatabaseConnection
{
/**
* Instance de la class SPDO
*
* @var SPDO
* @access private
* @static
*/
private static $_instance = null;

private $_handle;

private function __construct()
{

try
{
$this->_handle = new PDO("mysql:host=localhost; dbname=cdmef", 'root', '');
$this->_handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo 'Connection established and database';
echo "

";
}
catch (PDOException $e)
{
die('Connection failed or database cannot be selected : ' . $e->getMessage());
}
}



public function __destruct()
{
var_dump($this->_db); // Vérification

if (!is_null($this->_handle))
{
$this->_handle = null;
echo 'Connection closed.';
}

var_dump($this->_db); // Une dernière vérification pour voir si l'objet a été détruit
}

private function __clone()
{

}

public static function getInstance()
{
if (is_null(self::$_instance))
{
self::$_instance = new self();
}

return self::$_instance;
}

public function handle()
{
return $this->_handle;
}

}

?>


et ensuite par exemple dans ma classe Comment.php je l'utilise comme ça

require_once ("SPDO.php");

class Comment
{
/* Attributs */
private $_db;
private $_sql;
private $_statement;

/* Contructeur */
public function __construct()
{
$this->_db = DatabaseConnection::getInstance()->handle();
}

et la mon code .......

}
0
Rejoignez-nous