IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Classe database sqlite


Sujet :

PHP & Base de données

  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Juin 2020
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur commercial

    Informations forums :
    Inscription : Juin 2020
    Messages : 25
    Par défaut Classe database sqlite
    Bonjour tout le monde,

    Je démarre le POO en PHP. Je cherche déjà à connecter la base de données en sql.

    J'ai ce code mais je pense que j'ai mal adapté.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <?php
     
    namespace app;
     
    use PDO;
     
    class Database{
     
    	try
    	{
    		$DB = new PDO('sqlite:calibreDatabase.db');
    		$DB->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    	}
    	catch (Exception $e)
    	{
    		die('Erreur : ' . $e->getMessage());
        }
     
    }

  2. #2
    Expert confirmé
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 325
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 325
    Billets dans le blog
    17
    Par défaut
    Voici la doc PHP sur la POO à lire, tout y est détaillé : https://www.php.net/oop5

    Quand quelque chose ne va pas, donne le message d'erreur.

    La syntaxe de ta classe est invalide, tes instructions doivent être placées dans des méthodes.

    Ton try/catch ne devrait pas contenir de die(). En effet, par défaut une exception non rattrapée met fin au script, mais elle doit aussi pouvoir être rattrapée par l'utilisateur pour un traitement adéquat, ce que tu empêches.

    Si tu veux encapsuler PDO il existe plusieurs manières de faire.

    Par héritage, avec extends, MyDatabase va hériter de toutes les méthodes de PDO, et tu peux en ajouter d'autres si besoin :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    class MyDatabase extends PDO
    {
        public function __construct()
        {
            parent::__construct('sqlite:calibreDatabase.db'); // On appelle le constructeur de l'objet PDO parent
            $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $this->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
        }
    }
     
    try {
        $db = new MyDatabase();
        $data = $db->query('...')->fetchAll();
        print_r($data);
    } catch (Exception $e) { // On laisse la possibilité à l'utilisateur de gérer l'exception comme il veut
        // Affichage de l'exception et sortie du script
        print_r($e);
        exit;
    }

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Juin 2020
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur commercial

    Informations forums :
    Inscription : Juin 2020
    Messages : 25
    Par défaut
    Merci beaucoup !
    Dans le code que tu m'as donné, $parent n'est pas reconnu ? VSC m'indique que c'est une erreur.

  4. #4
    Expert confirmé
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 325
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 325
    Billets dans le blog
    17
    Par défaut
    Dans le code que tu m'as donné, $parent n'est pas reconnu ? VSC m'indique que c'est une erreur.
    Et sinon ça fonctionne ? Voir la config de VSC, je ne pourrai pas t'aider.

  5. #5
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 518
    Par défaut
    Bonjour,

    parent sans dollar, ceci indique que le constructeur doit hériter du constructeur parent PDO.

  6. #6
    Expert confirmé
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 325
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 325
    Billets dans le blog
    17
    Par défaut
    Citation Envoyé par Toufik83 Voir le message
    parent sans dollar, ceci indique que le constructeur doit hériter du constructeur parent PDO.
    Oups en effet, je corrige la coquille. Merci !

  7. #7
    Membre averti
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Juin 2020
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur commercial

    Informations forums :
    Inscription : Juin 2020
    Messages : 25
    Par défaut
    Merci à tous les 2, effectivement ça fonctionne ! Un grand merci.

  8. #8
    Membre averti
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Juin 2020
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur commercial

    Informations forums :
    Inscription : Juin 2020
    Messages : 25
    Par défaut
    Excusez-moi à tous les 2, mais finalement je bute encore pour appeler la classe.
    J'ai créé des classes pour faire mes requêtes sql puis manipuler les données comme je veux. Comme faire la liaison avec ma classe database que nous venons d'écrire ?

  9. #9
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 518
    Par défaut
    Bonjour,

    Montres nous la classe que tu veux utiliser avec celle qu'on vient d'écrire, et explique un peu ce que tu cherches à faire exactement.

  10. #10
    Membre averti
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Juin 2020
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur commercial

    Informations forums :
    Inscription : Juin 2020
    Messages : 25
    Par défaut
    Citation Envoyé par Toufik83 Voir le message
    Bonjour,

    Montres nous la classe que tu veux utiliser avec celle qu'on vient d'écrire, et explique un peu ce que tu cherches à faire exactement.
    Voici ma classe livre, permettant de récupérer les données de la base (id, titre, auteur).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <?php 
     
    namespace app\table;
     
    use Database;
     
    class livre{
     
        public static function getlast(){
            return $data::getdb()->query("
            SELECT *
            FROM books
            ", __CLASS__);
        }
     
        public function __get($key){
            $method = 'get' . ucfirst($key);
            $this->$key = $this->$method();
            return $this->$key;
        }
     
        public function getUrl(){
            return 'index.php?p=livre&id=' . $this->id;
        }
     
    }
    L'idée est de travaillé sur une base de données existante, externe à l'application. Il s'agit de visualiser les données. La base étant très complexe avec beaucoup de données différentes et n'ayant rien à voir entre elles, je pensais intéressant de séparer l'accès a la base avec une classe, puis écrire d'autres classes chacune correspondant à des objets. Ici, les livres. Le code sql ici est volontairement simple mais s'étend en vrai sur plusieurs dizaine de lignes.

  11. #11
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 602
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 602
    Billets dans le blog
    10
    Par défaut
    Bonjour,

    Je ne répondrai pas sur la partie PHP que je ne maîtrise pas, mais concernant la requête, il ne faut jamais utiliser SELECT * dans un traitement :
    • select * est instable : toute modification de la table ou de la vue impactera la requête
    • select * est couteux : toutes les colonnes sont ramenées alors que la plupart du temps, un traitement n'a besoin que d'une partie des colonnes.
      Le transport des données inutiles charge le réseau au détriment des performances de votre traitement et aussi des traitements qui s'exécutent en parallèle.

    Remplacez donc SELECT * par la liste des colonnes utiles

  12. #12
    Membre averti
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Juin 2020
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur commercial

    Informations forums :
    Inscription : Juin 2020
    Messages : 25
    Par défaut
    Merci, je note le conseil ! Ma requête SQL est bien plus longue et j'ai noté les titres des colonnes

  13. #13
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 518
    Par défaut
    Bonjour,

    La classe livre n'a aucun rapport avec les requêtes sql, elle doit s'occuper seulement de l'objet livre pas plus.

    il faudrait créer une classe dbManagerLivre héritante de livre, c'est cette classe qui doit gérer les requêtes sql :

    Classe Database :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    <?php 
    namespace Database;
    use \PDO;
    class Database extends \PDO{
        public function __construct()
        {
            parent::__construct('sqlite:calibreDatabase.db'); // On appelle le constructeur de l'objet PDO parent
            $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $this->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
        }
    }
    Classe livre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    <?php 
     
    namespace app\table;
    class livre{
    	protected $id,$name,$titre;
    	public function __construct($data){
    		/*Pour instancier un nouveau Livre manuellement lorsqu'on en a besoin */
    		if(is_array($data)){
    			foreach($data as $prop=>$value){
    				$method = 'set' . ucfirst($prop);
    				if(method_exists($this,$method))
    					$this->{$method}($value);
    			}
    		}
    	}
    	//getters
            public function getId(){return $this->id;}
    	public function getName(){return $this->name;}
    	public function getTitre(){return $this->titre;}
     
            //setters
    	protected function setId($id){$this->id=$id;}
    	protected function setName($name){$this->name=$name;}
    	protected function setTitre($titre){$this->titre=$titre;}
     
    	public function __get($key){
               $method = 'get' . ucfirst($key);
               $this->$key = $this->$method();
               return $this->$key;
            }
    	public function __set($name,$key){
              $method = 'set' . ucfirst($name);
              $this->{$method}($key);
           }
           public function getUrl(){
              return 'index.php?p=livre&id=' . $this->id;
           }
     
    }
    Classe dbManagerLivre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    <?php
    namespace app\dbManagers;//il faut que cette classe existe dans le dossier app/dbManagers ! 
    use Database;
    use app\table\livre; 
     class dbManagerLivre extends livre{
    	private static $db;
            public static function getAll(){
              return self::$db->query("
                SELECT id,name,titre
                FROM books
               ")
               ->fetchAll(\PDO::FETCH_CLASS,parent::class,["id","name","titre"]);
            }
     
            public function __construct(livre $lv=null,Database $db){
    		self::$db=$db;
           }
    }
    Page index de teste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    <?php
    /*Activer l'affichage des erreurs/avertissements*/
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);
     
    $db=new Database();
    $livre=new livre(['id'=>10,'name'=>"name livre 1","titre"=>"titre livre 1"]);
    $dbMng=new dbManagerLivre($livre,$db);
     
    $allBooks=$dbMng::getAll();
    foreach($allBooks as $book){
    	echo '<br />book id :'.$book->getId()."<br />"
    	.'book name :'.$book->getName()."<br />"
    	.'book titre :'.$book->getTitre().'<br />';
    }
    /*Affiche : 
    book id :1
    book name :name 1
    book titre :titre 1
    
    book id :2
    book name :name 2
    book titre :titre 2
    */
    Remarque : j'ai modifié les namespaces parce que j'ai créer un autoloader classique, ce qui n'est pas le cas pour toi...

    [EDIT] :
    Il est aussi utile de récupérer l'objet Database d'une façon statique afin de l'utiliser sans avoir à l'instancier avec le mot clé new...

  14. #14
    Membre averti
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Juin 2020
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur commercial

    Informations forums :
    Inscription : Juin 2020
    Messages : 25
    Par défaut
    Un grand merci. Après plusieurs ajustements suite à des erreurs, une dernière apparait :

    Nom : Capture.PNG
Affichages : 89
Taille : 33,1 Ko

  15. #15
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 518
    Par défaut
    L'erreur dit que la méthode setTitle() n'existe pas dans la classe livre, tu n'as qu'à remplacer setTitre() par setTitle() et n'oublis pas aussi le getter.

  16. #16
    Membre averti
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Juin 2020
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur commercial

    Informations forums :
    Inscription : Juin 2020
    Messages : 25
    Par défaut
    Parfait ça fonctionne !! Un grand grand merci !!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Erreur dataBase SQLite
    Par Nylwen dans le forum Android
    Réponses: 5
    Dernier message: 14/09/2012, 15h01
  2. Attach Database sqlite
    Par matini dans le forum PHP & Base de données
    Réponses: 0
    Dernier message: 20/01/2012, 10h18
  3. Réponses: 1
    Dernier message: 10/05/2011, 15h56
  4. [Debutant]JDBC MySQL Classe Database
    Par userB dans le forum JDBC
    Réponses: 2
    Dernier message: 04/02/2008, 17h54
  5. [MySQL] Classe database + connexion multiple + principe mal compris
    Par Rodrigue dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 14/08/2006, 14h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo