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 :

[PHP 5] Database Reflection


Sujet :

PHP & Base de données

  1. #1
    Expert confirmé
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Par défaut [PHP 5] Database Reflection
    Bonsoir à tous.

    Je suis en train de réfléchir à une architecture objet me permettant de faire de la réflexion d'une base de données MySQL. L'idée est de pouvoir fournir aux couches métier et présentation un visuel sur l'état de la base de données tant en termes de structure que de données. Ne me demandez pas pourquoi, on dira simplement que je travaille dans un contexte ou je n'ai pas le contrôle sur les base de données avec lesquelles travaillent mon application.
    Actuellement, si on prends le cas d'école "produit", je dispose d'un modèle sous forme de classe Product, d'un métier ProductManager, d'un agrégateur Products, d'un contrôleur ProductsController et de plusieurs templates de vues (edit, list et view). Le problème est que (trop) souvent, d'autres développeurs dont les application adressent également les bases de données changent le schéma, ce qui à pour incidence de revisiter une bonne partie des classes sus-nommées.
    Là ou je souhaite arriver c'est fournir un composant capable de faire de la réflexion sur les tables, les vues, les procédures et les databases - c'est à dire d'en connaitre le schéma, les intrications entre les entités, les relations etc.

    La définition des besoins fait apparaître la nécessité de reproduire le mécanisme des Reflector de PHP 5. Ma question est alors la suivante:
    est-il envisageable d'écrire une série de classes qui réalisent l'interface Reflector ?

    ORM et Frameworks s'abstenir, je n'en veux pas.

  2. #2
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    oui ça me semble faisable, y'a moyen de faire quelque chose de bien en plus
    par contre certaines info dépendent des SGBD et des droits dessus

  3. #3
    Expert confirmé
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Par défaut
    Je n'ai pas trouvé grand chose sur Google à ce sujet (je suis d'ailleurs tombé sur mon propre topic avec les mots clés "php database reflector" ). Il me semble que des framework de test comme PHPUnit utilisent une technologie comparable, on pourrait sûrement s'inspirer de leur fonctionnement.

    Enfin ma question n'était pas tant de l'ordre de la faisabilité - en réalité, j'ai déjà quelques ébauches de classes service capable de renvoyer une structure de table, de générer des requêtes et d'extraire les valeurs par défaut d'une table, ça marche assez bien soit dit en passant - mais plutôt d'un ordre logique: est ce que le prendre comme ça, c'est à dire étendre le mécanisme de réflexion de PHP, est une bonne ou mauvaise approche.

    Le but avoué est la génération de vues et de formulaires "à la volée", les plus malins l'auront deviné, je travaille sur des back-offices écrits en PHP

    par contre certaines info dépendent des SGBD et des droits dessus
    Tout à fait, mais la problématique est assez complexe comme ça sans devoir ajouter une couche d'abstraction (même si je vois déjà à quoi elle va ressembler). Je souhaite me concentrer sur MySQL, ensuite il sera toujours possible d'étendre en factorisant et en mettant des adaptateur partout.

  4. #4
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    Je trouve que c'est une bonne idée.

  5. #5
    Expert confirmé
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Par défaut
    Je constate que l'interface Reflector définit une méthode statique export. Dans le contexte de ReflectionClass, ça permet d'exporter la classe visiblement. Je ne comprends pas bien ce que cela signifie et comment l'implémenter dans mon cas.
    Auriez-vous des idées là dessus ?

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    oui Reflector c'est pour le rendre en texte, mais rien n'empeche d'avoir les valeurs

    ReflectionClass -> getMethods -> ReflectionMethod -> isPublic

    donc niveau table tu peux avoir par exemple

    ReflectionBase -> getTables -> ReflectionTable -> getEngine

  7. #7
    Expert confirmé
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Par défaut
    Ok, j'ai attaqué par le début, la classe ReflectionBase:

    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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
     
    class ReflectionBase implements Reflector {
     
        protected $_pdo;
     
        protected $_meta_inf;
     
        public function __construct ($dbname, PDO $pdo) {
            if ($pdo === null)
                throw new InvalidArgumentException("Second argument must be a valid PDO instance");
     
            $this->_pdo = $pdo;
     
            $query = "SELECT `CATALOG_NAME`,`SCHEMA_NAME`,`DEFAULT_CHARACTER_SET_NAME`,`DEFAULT_COLLATION_NAME`,`SQL_PATH`".
                     " FROM `information_schema`.`SCHEMATA` WHERE `SCHEMA_NAME`=:dbname";
     
            $stmt = $this->_pdo->prepare($query);
            $stmt->bindParam(':dbname', $dbname, PDO::PARAM_STR);
            if ($stmt->execute()) {
                if (!$stmt->rowCount())
                    throw new ReflectionException("Base $dbname does not exist");
     
                $this->_meta_inf = $stmt->fetch(PDO::FETCH_ASSOC);
            }
            else {
                $info = $this->_pdo->errorInfo();
                throw new RuntimeException ("PDOStatement execution failed: {$info[2]} with error code {$info[1]}");
            }
        }
     
        public function getCatalog () {
            return $this->_meta_inf['CATALOG_NAME'];
        }
     
        public function getSchema () {
            return $this->_meta_inf['SCHEMA_NAME'];
        }
     
        public function getDefaultCharset () {
            return $this->_meta_inf['DEFAULT_CHARACTER_SET_NAME'];
        }
     
        public function getDefaultCollation () {
            return $this->_meta_inf['DEFAULT_COLLATION_NAME'];
        }
     
        public function getSQLPath () {
            return $this->_meta_inf['SQL_PATH'];
        }
     
        public function getTable ($tablename) {
            $tablename = "`{$this->getSchema()}`.`$tablename`";
            return new ReflectionTable ($tablename);
        }
     
        public function getTables () {
            $query = "SELECT `TABLE_SCHEMA`,`TABLE_NAME` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA`=:schema";
     
            $stmt = $this->_pdo->prepare($query);
            $stmt->bindParam(':schema', $this->getSchema(), PDO::PARAM_STR);
            if ($stmt->execute()) {
                $list = array();
                foreach ($stmt as $row) {
                    list($schema, $table) = $row;
                    $list[] = new ReflectionTable("``$schema`.`$table`");
                }
                return $list;
            }
            else {
                $info = $this->_pdo->errorInfo();
                throw new RuntimeException ("PDOStatement execution failed: {$info[2]} with error code {$info[1]}");
            }
        }
     
        public function getView ($viewname) {
            // TODO
        }
     
        public function getViews () {
            // TODO
        }
     
        public function getProcedure ($procedurename) {
            // TODO
        }
     
        public function getProcedures () {
            // TODO
        }
     
        /**
         * -------------------------------------------------------------------------------------------------------------------------------------
         * Reflector methods
         */
     
        public static function export ($dbname, $return = false) {
            // TODO
        }
     
        public function __toString () {
            // TODO
        }
    }
    et déjà une première interogation: devrais-je conserver les statements dans une propriété statique de la classe ReflectionBase, quitte à devoir écrire une méthode privée _init ?

  8. #8
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    tu sais que avec PDO t'as FETCH_CLASS

    donc tu pourrais faire par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $stmt->fetchAll(PDO::FETCH_CLASS, 'ReflectionTable');

  9. #9
    Expert confirmé
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Par défaut
    Je sais mais
    PDO::FETCH_CLASS: returns a new instance of the requested class, mapping the columns of the result set to named properties in the class. If fetch_style includes PDO::FETCH_CLASSTYPE (e.g. PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE) then the name of the class is determined from a value of the first column.
    Or ici ce sont les propriété de l'objet en construction qu'on mets à jour.

    En revanche, ça peut être utile pour le factory de ReflectionTable. A voir.

    Pendant que je suis là, tu as un article ou tutorial sur les catalogues en MySQL, je ne les utilise jamais mais bon, je vais sûrement devoir l'implémenter ici.

  10. #10
    Expert confirmé
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Par défaut
    Bon, j'ai bien avancé. J'ai créé les classes suivantes
    - ReflectionBase
    - ReflectionTable
    - ReflectionView
    - ReflectionRoutine
    - ReflectionColumn
    Toutes réalisent l'interface Reflector et disposent d'une méthode __toString équivalente à celle de ReflectionClass par exemple.

    Voic un exemple:
    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
     
    include_once "libraries/data/reflection/MySQL/ReflectionBase.class.php";
    include_once "libraries/data/reflection/MySQL/ReflectionTable.class.php";
    include_once "libraries/data/reflection/MySQL/ReflectionColumn.class.php";
     
    $pdo = new PDO("mysql:dbname=testbase;host=127.0.0.1", "root", "");
     
    $column = new ReflectionColumn("testbase.testtable.testcol1", $pdo);
    echo $column . '<hr />';
     
    $table = new ReflectionTable("testbase.testtable", $pdo);
    echo $table . '<hr />';
     
    $base =new ReflectionBase("testbase", $pdo);
    echo $base . '<hr />';
     
    foreach ($base->getTables() as $table) {
        echo "TABLE {$table->getName()} <br />";
        foreach ($table->getColumns() as $column) {
            echo " COLUMN {$column->getName()} <br />";
        }
    }
    echo "<hr />";
     
    echo $column->getTable()->getBase()->getName() . "<hr />";
    echo $column->getTable()->getColumn('testcol1')->getBase()->getName() . "<hr />";
     
    echo $table->getCreateTable() . '<hr />';
    echo $column->getDefault() . '<hr />';
     
    ReflectionTable::export("testbase.testtable", $pdo);
    Cet exemple produit:
    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
     
    Column [ column testcol1 ] { type : int(11) , pos : 1 }
     
    Table [ table testtable ] { Columns [3] { Column [ column testcol1 ] { type : int(11) , pos : 1 } Column [ column testcol2 ] { type : int(11) , pos : 2 } Column [ column testcol3 ] { type : int(11) , pos : 3 } } }
     
    Base [ database testbase ] { - Tables [1] { Table [ table testtable ] { Columns [3] { Column [ column testcol1 ] { type : int(11) , pos : 1 } Column [ column testcol2 ] { type : int(11) , pos : 2 } Column [ column testcol3 ] { type : int(11) , pos : 3 } } } } } 
     
    TABLE testtable
    COLUMN testcol1
    COLUMN testcol2
    COLUMN testcol3
     
    testbase
     
    testbase
     
    CREATE TABLE `testtable` ( `testcol1` int(11) NOT NULL, `testcol2` int(11) NOT NULL, `testcol3` int(11) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1
     
    Table [ table testtable ] { Columns [3] { Column [ column testcol1 ] { type : int(11) , pos : 1 } Column [ column testcol2 ] { type : int(11) , pos : 2 } Column [ column testcol3 ] { type : int(11) , pos : 3 } } }
    Je pense qu'on est sur la bonne voie. Mais pensez-vous qu'il soit judicieux de faire hériter toute ces classe d'une classe abstraite ReflectionDatabase ou ReflectionMySQL ??

  11. #11
    Expert confirmé
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Par défaut
    Pour revenir à ce que tu disait,

    tu sais que avec PDO t'as FETCH_CLASS

    donc tu pourrais faire par exemple :
    Code :

    $stmt->fetchAll(PDO::FETCH_CLASS, 'ReflectionTable');
    FETCH_INTO semble fonctionner dans notre cas, je vais voir si c'est possible avec $this.

  12. #12
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Citation Envoyé par Benjamin Delespierre Voir le message
    Mais pensez-vous qu'il soit judicieux de faire hériter toute ces classe d'une classe abstraite ReflectionDatabase ou ReflectionMySQL ??
    L'héritage n'a d'intérêt que si tu souhaites une racine commune et que cette racine est nécessaire par des propriétés et ou des méthodes partagée et partageables entre les objets.

    Je ne les ferais pas toutes hériter de reflexionBase, je ne vois pas trop les propriétés et/ou méthodes communes.

    Par contre, je découperais reflexionBase en deux "étage" un reflexionBase et un reflexionBaseMaBase qui permettrait d'adapter facilement sur d'autre base de données.

    De plus je ne sais pas si tu n'aurais pas intérêt à gérer un objet reflexionConnction a part.

    Et si tu n'aurais pas intérêt à gérer un objet collection qui implémenterais arrayAccess et iteration qui serait rattaché à base pour inclure une collection des tables et à table pour une collection des colonnes.

    Et enfin, j'ai l'impression qu'il manque une notion d'objet enregistrement mais peut-être est-il mélangé a table ?

  13. #13
    Expert confirmé
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Par défaut
    Salut Michael, merci pour ton post.

    Si j'ai parlé d'héritage, c'est parce que toutes ces classes partagent:
    - le fait qu'elles réalisent Reflector
    - la signature de leur constructeur
    - les propriété $_pdo et $_meta_inf
    Mais je me demande si cette relation caractérise bien un "est un espèce de".

    Par contre, je découperais reflexionBase en deux "étage" un reflexionBase et un reflexionBaseMaBase qui permettrait d'adapter facilement sur d'autre base de données.
    Tu veux dire sur un autre SGBD ? Pour l'instant c'est pas au programme, au besoin je mettrai des adaptateur pour faire ça.
    Je ne vois pas trop d'intérêt dans la classe reflectionBaseMaBase puisque new ReflectionBase('MaBase') est fait pour ça
    ReflectionBase porte par ailleurs une méthode statique getBases() capable renvoyer tous les schémas sous forme de tableau de ReflectionBase.

    De plus je ne sais pas si tu n'aurais pas intérêt à gérer un objet reflexionConnction a part.
    Non, vu que les objets portent leur connection PDO, ce n'est pas nécéssaire.

    Et si tu n'aurais pas intérêt à gérer un objet collection qui implémenterais arrayAccess et iteration qui serait rattaché à base pour inclure une collection des tables et à table pour une collection des colonnes.
    Oui, si on voulait mettre en cache c'est ce qu'il faudrait faire. Mais ça rends la gestion des instances beaucoup plus complexe car on aurait des aggregations de partout or je veux qu'on puisse n'utiliser par exemple que la classe ReflectionTable sans avoir au préalable instancié de ReflectionBase.

    Et enfin, j'ai l'impression qu'il manque une notion d'objet enregistrement mais peut-être est-il mélangé a table ?
    Pourrais-tu être plus explicite ?

    -- Edit
    Je crois comprendre ce que tu veux dire quand tu parle des objets enregistrement, tu veux dire des objets ReflectionRecord c'est ça ?
    Le problème est que ces classes de réflection ne portent que sur la structure des éléments du SGBD, les enregistrements sont gérés par une chouche supérieure (le DAO).

  14. #14
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Citation Envoyé par Benjamin Delespierre Voir le message
    Tu veux dire sur un autre SGBD ?
    Qui peut le plus peut le moins.

    Non, vu que les objets portent leur connexion PDO, ce n'est pas nécessaire.
    J'aurais toujours (comme pour la remarque précédente) un regard qui porte au loin. L'idée n'est pas de remplacer la couche PDO, juste de pouvoir jongler avec deux base ou deux accès différent à la base en même temps. Dans le style, on ne sais jamais...

    Oui, si on voulait mettre en cache c'est ce qu'il faudrait faire. Mais ça rends la gestion des instances beaucoup plus complexe car on aurait des aggregations de partout or je veux qu'on puisse n'utiliser par exemple que la classe ReflectionTable sans avoir au préalable instancié de ReflectionBase.
    Tu as déjà des agrégations vu que ton objet base va retrouver une série potentiel de table et que l'objet table va retrouver une série de champs. Pouvoir y accéder par un arrayAccess est un avantage (je crois). Le fait de mutualiser la gestion de ces collection me semble aller plutôt dans une idée de simplification. Tu pourrais alors récupérer une table par un $reflextionBase['maTable']->getColumns().


    Dans l'objet reflectionBase, pourquoi ne stockes tu pas ta liste des tables dans getTables() ? Ainsi, si la demande est faîte deux fois il n'y a qu'une requête SQL (la premières). Et tu peux récupérer ton objet table, pour la méthode getTable, directement dans le tableau, s'il existe et le générer le cas échéant.

    Par contre, j'ai peut-être une vision trop généraliste et pas suffisamment cas particulier. Désolé.

  15. #15
    Expert confirmé
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Par défaut
    Qui peut le plus peut le moins.
    Oui mais comme je l'ai dit, il vaut mieux faire ça avec des adaptateur qu'avec des classes spécialisés comme ReflectionMySQLTable, ReflectionOracleTable etc. Il vaut mieux garder ReflectionTable et lui fournir une méthode attach(ReflectionAdapter $adapter) où ReflectionAdapter serait une classe abstraite ayant MySQLReflectionAdapter et OracleReflectionAdapter pour fille.
    Mais comme je l'ai dit, on en es pas là.

    J'aurais toujours (comme pour la remarque précédente) un regard qui porte au loin. L'idée n'est pas de remplacer la couche PDO, juste de pouvoir jongler avec deux base ou deux accès différent à la base en même temps. Dans le style, on ne sais jamais...
    Deux accès différents pourquoi pas, encore que, vu que PHP est synchrone, je ne vois pas trop l'intérêt de faire des pools. Si tu veux utiliser deux connection différentes, tu peux toujours le faire avec deux instances de PDO différentes.
    Deux base, pour quoi faire ?? Un table n'appartient pas à plusieurs bases ni plus qu'une colonne n'appartiens à deux tables.

    Tu as déjà des agrégations vu que ton objet base va retrouver une série potentiel de table et que l'objet table va retrouver une série de champs.
    Non, ce sont des factories. Si on voulait vraiment implémenter la hiérarchie établie entre les bases, tables et colonnes, on aurait un problème de direction dans notre mécanisme de cache. Aussi vrai qu'une base à des tables, les tables appartiennent à une base et on doit pouvoir se balader dans les deux sens. Or ce serait logiquement de la responsabilité de ReflectionBase de porter les ReflectionTables qui porteraient à leur tour les ReflectionColumn. Que se passerait-il alors si on instancie un ReflectionColumn et qu'on veut obtenir la base ?

    Ainsi, si la demande est faîte deux fois il n'y a qu'une requête SQL (la premières). Et tu peux récupérer ton objet table, pour la méthode getTable, directement dans le tableau, s'il existe et le générer le cas échéant.
    La mise en cache est un peu plus compliqué car on ne fait pas que descendre dans la hiérarchie base-table-colonne.

    Par contre, j'ai peut-être une vision trop généraliste et pas suffisamment cas particulier. Désolé.
    J'essaie aussi de rester généralise, tout en restant simple dans la conception. C'est pourquoi je pense que la mise en cache serait complexe à implémenter pour un résultat pas forcément spectaculaire au niveau des perfs (j'ai fait des bench et c'est déjà satisfaisant comme ça). De plus, si on veut aller au bout du raisonement, il faut pouvoir sérialiser tout ça, et là on part dans une dérive de conception.

  16. #16
    Expert confirmé
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Par défaut
    Hello

    Bon j'ai pas abandonné le thread hein ! Vous trouverez dans la pj du post les classes dans leur état de délabrement actuel. Faisez des test et dites-moi ce que vous en pensez.
    Fichiers attachés Fichiers attachés

Discussions similaires

  1. [2.x] php app/console doctrine:mapping:convert --from-database
    Par aitiahcene dans le forum Symfony
    Réponses: 0
    Dernier message: 25/04/2012, 13h40
  2. Connaissez vous un PHP Database toolkit ?
    Par oxman dans le forum Bibliothèques et frameworks
    Réponses: 6
    Dernier message: 06/03/2011, 15h36
  3. Erreur sous PHP MyAdmin (PMA database?)
    Par Matlight dans le forum Installation
    Réponses: 5
    Dernier message: 28/10/2010, 19h38
  4. Réponses: 17
    Dernier message: 08/08/2006, 14h08
  5. Problème avec RDB$DATABASE et PHP
    Par Darkdaemons dans le forum Connexion aux bases de données
    Réponses: 2
    Dernier message: 16/01/2006, 14h53

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