Classe de connection PDO : tester si une base existe

Messages postés
36
Date d'inscription
mardi 23 novembre 2010
Statut
Membre
Dernière intervention
4 avril 2013
- - Dernière réponse : TychoBrahe
Messages postés
1309
Date d'inscription
samedi 31 janvier 2009
Statut
Membre
Dernière intervention
5 juin 2013
- 2 févr. 2012 à 16:11
Bonsoir,
J'essaie désespérément de tester si une base de données existe... mais je ne vois pas comment faire pour me servir des erreurs 'catchées'. J'utilise pour me connecter à ma base la classe PDO, avec un singleton.
Inutile de préciser que je débute de chez je débute.
Merci de votre aide.
ClR
Afficher la suite 

12 réponses

Messages postés
1654
Date d'inscription
dimanche 7 septembre 2008
Statut
Membre
Dernière intervention
11 septembre 2013
9
0
Merci
bonjour

http://php.net/manual/fr/pdo.connections.php

Tapez le texte de l'url ici.


<?php
// Exemple #1 Connexion Ó MySQL


$host='localhost';
$user='root';
$pass='';
$base='test';
$table='eleve';





$dbh = new PDO('mysql:host='.$host.';dbname='.$base, $user, $pass);

try {
    
    $dbh = new PDO('mysql:host='.$host.';dbname='.$base, $user, $pass);
    
    echo 'vous êtes connecté !
';
    
    $dbh = null;
}

      catch (PDOException $e) {
          print "Erreur vous êtes non connecté ! erreur en cours : " . $e->getMessage() . "
";
          die();
      }



// S'il y a des erreurs de connexion, un objet PDOException
// est lancÚ. Vous pouvez attraper cette exception si vous
// voulez gÚrer cette erreur, ou laisser le gestionnaire 
// global d'exception dÚfini via la fonction set_exception_handler() la traiter.

//Exemple #2 Gestion des erreurs de connexion

try {
    $dbh = new PDO('mysql:host='.$host.';dbname='.$base, $user, $pass);
    foreach($dbh->query('SELECT * from '.$table) as $row) {
    
    echo '';
    print_r($row);
    echo '

';
    }
    $dbh = null;
} catch (PDOException $e) {
    print "Erreur !: " . $e->getMessage() . "
";
    die();
}
?>



question : que veux tu faire avec le singleton !
peux on voir ton code



Bonne programmation !
Commenter la réponse de cod57
Messages postés
36
Date d'inscription
mardi 23 novembre 2010
Statut
Membre
Dernière intervention
4 avril 2013
0
Merci
Bonjour...
Finalement je me suis débrouillée comme ça, mais je ne sais pas si ça peut se faire ainsi. J'ai fait une méthode sans les paramètres de la base, ce qui me permet de vérifier si elle existe, comme ça :
$pdo = PDO2::getBase();
$requete = 'CREATE DATABASE IF NOT EXISTS '.DBNAME.' DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci';
$teste = $pdo->prepare($requete)->execute();
//si connexion impossible, db existe pas
if($teste === true)
{
//creation de base et tables associées
}
else
die();


J'ajoute juste avant de mettre ma classe singleton que cette page et cette fonction ne servent qu'une fois.
et le singleton... pour n'avoir qu'une connexion

<?php
//SINGLETON PR PDO
class PDO2 extends PDO
{
private static $_instance;

/* CONSTRUCTEUR : héritage public obligatoire par héritage de PDO */
public function __construct( )
{
}
// End of PDO2::__construct() */

/* SINGLETON : getInstance */
public static function getInstance()
{
if (!isset(self::$_instance))
{
try
{
//CONNEXION
self::$_instance = new PDO(DSN, USER, PASSWORD);
}
catch (PDOException $e)
{
print 'Erreur : '.$e->getMessage().'
';
echo 'N° : '.$e->getCode().'
';
echo 'Ligne n° : '.$e->getLine();
die();
}
}
return self::$_instance;
}
// End of PDO2::getInstance() */

/* getBase */
public function getBase()
{
try
{
//CONNEXION
$instance = new PDO(DRIVER.':host='.HOST, USER, PASSWORD,
array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
}
catch (PDOException $e)
{
print 'Erreur : '.$e->getMessage().'
';
echo 'N° : '.$e->getCode().'
';
echo 'Ligne n° : '.$e->getLine();
die();
}
return $instance;
}
}

merci de ton aide. :)
Commenter la réponse de 555clR
Messages postés
1309
Date d'inscription
samedi 31 janvier 2009
Statut
Membre
Dernière intervention
5 juin 2013
11
0
Merci
Salut,

Je me permet de préciser que, dans le cas de MySQL uniquement, tu peux interroger la base information_schema afin d'avoir ton information. A noter que tu peux le faire bien que tu utilises une autre base. Voici un exemple qui retourne la liste de toutes les tables de la abse de donnée actuellement utilisée :
SELECT `TABLE_NAME` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = DATABASE();

J'insiste lourdement sur le fait que ceci est spécifique à MySQL (et assimilés) et ne saurait s'appliquer aux autres sgbdr.

et le singleton... pour n'avoir qu'une connexion

Perso je pense que ce soit une bonne idée. Il n'est pas impossible de devoir travailler avec plusieurs bases de données différentes simultanément, situés sur différents serveurs. Certes, en arriver là n'est pas si très fréquent et peut être la conséquence d'un mauvais design, mais ce n'est pas impossible.
Commenter la réponse de TychoBrahe
Messages postés
36
Date d'inscription
mardi 23 novembre 2010
Statut
Membre
Dernière intervention
4 avril 2013
0
Merci
Bonjour et merci de votre aide et de vos conseils.
La question me taraude quand même... on peut faire ce que je fais là ?? je veux dire... ça se fait ? (ça me paraît un peu lourdos mais je n'ai pas su faire autrement)
(et désolé pour les balises php manquantes tout à l'heure...)

<?php
//SINGLETON PR PDO
class PDO2 extends PDO
{
private static $_instance;

/* CONSTRUCTEUR : héritage public obligatoire par héritage de PDO */
public function __construct( )
{
}
// End of PDO2::__construct() */

/* SINGLETON : getInstance */
public static function getInstance()
{
if (!isset(self::$_instance))
{
try
{
//CONNEXION
self::$_instance = new PDO(DSN, USER, PASSWORD);
}
catch (PDOException $e)
{
print 'Erreur : '.$e->getMessage().'
';
echo 'N° : '.$e->getCode().'
';
echo 'Ligne n° : '.$e->getLine();
die();
}
}
return self::$_instance;
}
// End of PDO2::getInstance() */

/* getBase */
public function getBase()
{
try
{
//CONNEXION
$instance = new PDO(DRIVER.':host='.HOST, USER, PASSWORD,
array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
}
catch (PDOException $e)
{
print 'Erreur : '.$e->getMessage().'
';
echo 'N° : '.$e->getCode().'
';
echo 'Ligne n° : '.$e->getLine();
die();
}
return $instance;
}
} 
Commenter la réponse de 555clR
Messages postés
1309
Date d'inscription
samedi 31 janvier 2009
Statut
Membre
Dernière intervention
5 juin 2013
11
0
Merci
on peut faire ce que je fais là ?? je veux dire... ça se fait ? (ça me paraît un peu lourdos mais je n'ai pas su faire autrement)

Personnellement non. Faire une classe qui hérite de PDO afin de se simplifier la vie compte tenu de l'environnement d'accord, mais là en l'occurrence tu ne te simplifie rien du tout, bien au contraire.

Après il y a deux choses que tu fais qui ne se font vraiment pas :
1. Afficher l'erreur à l'utilisateur. Loger les erreur ok, c'est très bien, mais l'utilisateur final ne doit avoir aucune connaissance du détail de l'erreur, on se contente de lui en envoyer une générique.
2. Mélanger l'objet et l'impératif. Essaye donc de faire un choix, l'un ou l'autre, mais pas les deux stp.
Commenter la réponse de TychoBrahe
Messages postés
36
Date d'inscription
mardi 23 novembre 2010
Statut
Membre
Dernière intervention
4 avril 2013
0
Merci
Par rapport au point 1, il vaudrait mieux que je fasse ça ?
try
{
//...
}
catch (PDOException $e)
{
$e;
}
pour le second point je ne vois pas ce que tu veux dire...
merci de ton aide en tous les cas
Claire
Commenter la réponse de 555clR
Messages postés
1309
Date d'inscription
samedi 31 janvier 2009
Statut
Membre
Dernière intervention
5 juin 2013
11
0
Merci
Nope. Ce que tu devrais faire, par exemple, c'est catcher les exception au niveau de l'application elle même (et non au niveau local de ta connexion SQL) et, lorqu'il y en a une, avoir une gestion de cette forme :
1. Je log l'erreur quelque part (eg: fichier custom, déclenchement d'erreur php si jamais display_errors est à off et log_errors à on, etc)
2. Affichage d'un message d'erreur générique à l'utilisateur. (eg: "Une erreur s'est produite, veuillez nous excuser pour ce désagrément.").

Ainsi : Toi tu as le message d'erreur quelque part, et en plus de manière asynchrone. L'utilisateur à un message qui a du sens pour lui et ne divulgue rien sur ce que tu as fait.

Bref, set_exception_handler() peut t'aider, mais ce n'est pas la seule manière de faire.

Au passage, définir une gestion d'exceptions globale ne t'empêche pas d'en faire au niveau local dans certaines situations particulières hein ;) Par exemple, si une exception n'empêche pas le fonctionnement de l'application, alors il faut l'attraper au lieux de tout arrêter.
Commenter la réponse de TychoBrahe
Messages postés
1654
Date d'inscription
dimanche 7 septembre 2008
Statut
Membre
Dernière intervention
11 septembre 2013
9
0
Merci
/* CONSTRUCTEUR : héritage public obligatoire par héritage de PDO */


autrement à lire

Tapez le texte de l'url ici.

mais l'utilisateur final ne doit avoir aucune connaissance du détail de l'erreur
complètement d'accord


Bonne programmation !
Commenter la réponse de cod57
Messages postés
36
Date d'inscription
mardi 23 novembre 2010
Statut
Membre
Dernière intervention
4 avril 2013
0
Merci
ouais... je me suis bien cassée les dents à vouloir attraper mes erreurs avec set_exception_handler()... je n'arrive pas à en récupérer les n° de code pour en faire quelque chose et ma classe me pose de sacrés pb...
pis je m'emmêle les pinceaux...en même temps, les classes et pdo sont deux choses nouvelles pour moi.

je pensais faire une nouvelle propriété dans ma classe avec une méthode privée et une publique pour la consulter

<?php private $exception_handler = array();

private function exception_handler($e) {
 return array("mess" => $e->getMessage(), "code" => $e->getCode(), "line" => $e->getLine());
}?>


<?php get_exception_handler()
{
  return $this->_exception_handler
}?>


et puis j'avais mis dans mon catch de l'instance :
<?php catch (PDOException $e)
{
  exception_handler($e)
}?>


... euh ... jsais pu où j'en suis là...
I need help !
Commenter la réponse de 555clR
Messages postés
1309
Date d'inscription
samedi 31 janvier 2009
Statut
Membre
Dernière intervention
5 juin 2013
11
0
Merci
Heu...

<?php

$exception_handler = function($exception) {
  // whatever to log the exception
  die();
};
set_exception_handler($exception_handler);

?>

Juste au début du code, genre dans un fichier common.php inclu "partout" (enfin partout où c'est nécessaire). Pourquoi aller chercher plus loin ?
Commenter la réponse de TychoBrahe
Messages postés
36
Date d'inscription
mardi 23 novembre 2010
Statut
Membre
Dernière intervention
4 avril 2013
0
Merci
bonjour et merci beaucoup de tes réponses tout d'abord. Je suis désolée quelque chose m'échappe. Je ne suis pas sensée utiliser ma classe étendue de pdo... ? enfin je veux dire, mettre dedans le code que je veux faire, et qui est en rapport avec ?
Disons que je suis en pleine rénovation d'un petit site et j'essaie autant que faire se peut d'y faire le ménage et de ranger mes affaires tout en essayant d'intégrer de nouvelles choses. dont un petit peu d'objet avec quelques classes simples, l'utilisation de pdo et le singleton.
bref tout ça pour dire que l'objet j'y comprends pas grand chose encore et je suis surprise d'intégrer ce bout de code tout seul.
un ingrédient m'échappe.
par contre je pars au boulot. je n'aurais pas de réponse avant ce soir... merci encore et bonne journée
Commenter la réponse de 555clR
Messages postés
1309
Date d'inscription
samedi 31 janvier 2009
Statut
Membre
Dernière intervention
5 juin 2013
11
0
Merci
Je ne suis pas sensée utiliser ma classe étendue de pdo... ?

Tu peux oui, mais tu n'est pas obligée. Demande toi d'abord ce que ça t'apporte vraiment.

l'utilisation de pdo et le singleton

Comme je disais, le singleton est d'après moi une mauvaise idée. Si son but est juste d'avoir un contexte global pour accéder à ta db, alors autant utiliser $GLOBALS ($GLOBALS['mon_projet']['db'] = new PDO('blah blah');).
Commenter la réponse de TychoBrahe