Journal Api php5 mysql object = phpmyobject

Posté par  (site Web personnel) .
Étiquettes : aucune
0
19
avr.
2007
Je viens de mettre à dispo sur sourceforge une API php5 qui permet de manipuler les résultats d'une base mysql en les transformant en objets.

En gros, dynamiquement ça récupère les tuples d'un select avec des jointures, les sectionne et crée des objets qui hérite nt des attributs de chaque table.

C'est juste un essai d'implémentation d'une interface que j'avais écrit. Ca n'est pas foncièrement utile mais bon on ne sait jamais...

https://sourceforge.net/projects/phpmyobject/

Si vous avez des idées d'améliorations, contactez moi en privée, je vous donnerais un accès sur le cvs.
  • # Soucis

    Posté par  (site Web personnel) . Évalué à 2.

    Déjà ton archive semble corrompue :'(

    Sinon quel est l'utilisation et son intérêt ?

    Moi ce que j'aimerais avoir un jour serait un pdo vraiment complet pour toutes les dbs (enfin pgsql/mysql/sqlite)

    Qu'on puisse appeler comme une classe.
    (avec si possible de la cache et autre)
    • [^] # Re: Soucis

      Posté par  . Évalué à 3.

    • [^] # Re: Soucis

      Posté par  (site Web personnel) . Évalué à 1.

      Pour l'archive, je ne sais pas d'ou ça vient. J'ai rencontré le même problème, je l'ai réuploadé et ça a l air de fonctionner.

      l api n'est pas complète, mais bon ça fait clairement pas ce qui t intérresses. C'est pas comme une class qui implémenterait jdbc:odbc. C'est pas non plus comme pear.

      l'exemple d'utilisation est dans la test class. Une fois que t as renseigné les paramêtres mysql, Tu peux récupérer n''importe quel enregistrement d'une de tes tables et le manipuler comme un objet.

      Par exemple
      tu passes un "select * from db_user, db_ville limit 1" à ton controleur.

      Il va te créer deux objets disctints(c'est ça l'essentiel) user et ville que tu peux manipuler avec les getter et setter.

      Pareil si tu fais une jointure avec plus de 2 tables.

      genre:
      $object->getAttribute('user_login') va te sortir le nom de ton user.

      etc ...
      • [^] # Re: Soucis

        Posté par  . Évalué à 1.

        C'est pas que ce soit mal, mais en fait tu essaie de faire la même chose qu'avec RoR ?

        Avec ce type de programmation, ne plus écrire de lourde requêtes sql c'est un réel plaisir. ( je me doute que tu n'en ai pas encore arrivé la ) je me mets ca dans un coin voir comment ca fonctionne et si ca peut m'être utile toussa.

        Allez tous vous faire spéculer.

        • [^] # Re: Soucis

          Posté par  (site Web personnel) . Évalué à 1.

          je ne connais pas les subtilités de ROR en terme de manipulation d'objets, mais c'est bien orienté modèle vue contrôleur.

          Mon projet était en premier lieu de concevoir une interface, et ensuite de l'implémenter .

          Je ne pense pas que je refasse de mise à jour, ou que je maintienne cette API.

          La seule chose que je vais apporter à court terme c'est:
          - une contrainte sur l'unicité des primary keys pour qu'un objet soit unique,
          - que chaque objet soit classé dans une map en fonction de son type (et non plus dans une seule map)
          - implémenter la méthode pour updater les tables sql.
          - peut être et la c'est du domaine du rêve, implémenter un système relationnel objet
          • [^] # Re: Soucis

            Posté par  . Évalué à 2.

            J'ai pas regardé en détails, mais à première vue, ça me fait penser à l'ORM Propel [1] (utilisée par le framework Symfony). Je me trompe ?

            [1] http://propel.phpdb.org/
            • [^] # Re: Soucis

              Posté par  (site Web personnel) . Évalué à 1.

              ouai par rapport au code fournis en exemple sur la première page:

              $book = BookPeer::retrieveByPK(5);
              $book->setTitle('The Propel Story');
              $book->save();

              ça y ressemble. Sauf que ça me semble plus lourd à gérer. En fait, mon api gère elle même dynamiquement le nom des attributs.

              exemple t as une table

              book
              ====
              titre
              auteur

              le code équivalent à ce qui est écrit au dessus serait:
              $book ->setAttribute('titre', 'The Propel Story');
              $book->setAttribute('auteur', 'toto');
              $book->save(); (non implémenté)

              L'intérêt est donc la dynamique étant donné qu'il n'y a pas de getter/setter à écrire.

              Mais bon le truc le plus important c'est pas la manipulation des attributs, c'est la gestion des jointures de pouvoir créer plusieurs objets qui correspondent aux différentes tables à partir d'une seule ligne résultat.

              La problèmatique est que SQL ne renvoit pas la provenance des résultats en fonction des tables.
              • [^] # Re: Soucis

                Posté par  (site Web personnel) . Évalué à 1.

                plus dans le genre doctrine
                (http://www.phpdoctrine.net/doctrine/manual/documentation2.ph(...)


                $books = $conn->getTable("Books");
                $book = $books->findByDql("isbn = '978-2849464984'")
                $book ->titre = 'The Propel Story';
                $book['auteur'] = 'toto';
                $book->save();
                • [^] # Re: Soucis

                  Posté par  (site Web personnel) . Évalué à 1.

                  En fait, dans l'exemple ci dessus tu n'as qu'une table.

                  Le postulat de base concernant l'utilisation de cette api est de considérer chaque enregistrement contenu dans une seul table comme un objet.

                  Si tu fais un select sur deux tables jointes, tu récupères une seule ligne de résultat.

                  Hors si le résultat provient de deux tables à la fois, le seul objet que tu vas créer ne peut être considéré comme un objet enregistrement.

                  L'api pour chaque ligne de résultat va donc créer autant d'objets distincts qu'il y a de tables.

                  Je prend un exemple

                  select * from db_user, db_town limit where db_user.id_town=db_town.id_town 1;

                  avec
                  db_user
                  =======
                  id _user = 1
                  user_nom = toto
                  id_town = 1

                  et
                  db_town
                  =======
                  id_town = 1
                  town_nom = toulouse

                  le résultat de la requête sql va être:
                  id_user user_nom user_ville id_town town_nom
                  1 toto 1 toulouse

                  l'api va donc crée 2 objets distincts et non un seul.

                  Un objet db_user qui a comme attribue les noms de la champs de la table db_user, et un objet db_town qui a les attributes de la table db_town
                  • [^] # Re: Soucis

                    Posté par  (site Web personnel) . Évalué à 2.

                    En fait, dans l'exemple ci dessus tu n'as qu'une table. Le postulat de base concernant l'utilisation de cette api est de considérer chaque enregistrement contenu dans une seul table comme un objet.


                    Ce qui est en contradiction avec ton doux rêve de mapping relationnel objet. Comme je dis dans un commentaire plus bas, le mapping objet ne se résume pas à une table = un objet, mais il est normalement possible de faire plusieurs tables = un objet.
                    • [^] # Re: Soucis

                      Posté par  (site Web personnel) . Évalué à 1.

                      >> un objet ne se résume pas à une table = un objet, mais il est normalement possible de faire plusieurs tables = un objet.

                      Oui c'est possible c'est le comportement par défaut de la fonction php5 mysql_fetch_object

                      http://fr.php.net/manual/fr/function.mysql-fetch-object.php

                      qui te renvoit chaque tuple sous la forme d'un seul et unique objet...

                      Ca n'a donc pas d'intérêt de développer une api qui fasse cela.
              • [^] # Re: Soucis

                Posté par  (site Web personnel) . Évalué à 2.

                Sauf que ça me semble plus lourd à gérer.


                Mouai. Alors d'une part, je trouve plus simple d'écrire

                $book->setTitle('The Propel Story');

                Plutôt que

                $book ->setAttribute('titre', 'The Propel Story');

                Ensuite, tu as du raté quelque chose en PHP5, ce sont les méthodes magiques __getter__ et __setter__ qui peuvent t'éviter d'écrire des methodes setters et getters ;-)


                c'est la gestion des jointures de pouvoir créer plusieurs objets qui correspondent aux différentes tables à partir d'une seule ligne résultat. La problèmatique est que SQL ne renvoit pas la provenance des résultats en fonction des tables.


                D'où l'utilisation avec jDao, dans mon framework Jelix, d'un fichier XML qui explicite le mapping à faire. Cela permet ensuite à jDao de compiler à la volée des classes PHP (et les requêtes qui vont avec) et de savoir à jDao quel champs appartient à quelle table. (et je précise que le fichier XML peut être généré directement à partir de la table via un script en ligne de commande). http://jelix.org/articles/tutoriel/utiliser-dao .

                Cela a aussi l'avantage d'implémenter en partie ce que tu appelle du domaine du rêve dans un commentaire précédent : un système relationnel objet.

                En effet, faire du mapping objet, ce n'est pas seulement faire "une table = un objet" (sinon ça sert pas à grand chose, autant utiliser l'api proposée par PHP : http://fr.php.net/manual/fr/ref.mysqli.php qui manipule des objets), mais plusieurs tables = un objet. Bref, permettre la possibilité qu'un objet tire ses informations de plusieurs tables à la fois.
                • [^] # Re: Soucis

                  Posté par  (site Web personnel) . Évalué à 2.

                  bah si tu utilises un langage de script, autant tirer parti de l'interpréteur et ne pas développer comme si c'était du compilé.

                  Avoir des méthodes setTitle cela sous entend que tu vas avoir des classes différentes pour chaque type d'objets embarquant leurs propres méthodes pour manipuler les attributs.

                  Ici, t'as une seule classe mère tuple qui possède donc les deux méthodes, + simple + élégant après tu peux bien entendu créer des classes filles avec des méthodes setTitle, mais ça n'a aucun intérêt car la class mère à la capacité de le faire.

                  L'utilité de manipuler des objets distincts est de pouvoir ensuite modifier , et enregistrer les objets ensuite dans la base.

                  Avec la méthode générique , extraire une ligne et la considérer comme un seul objet, c'est dans l'optique de l'afficher.

                  De même si tu modifies la valeur d'un de tes attributs, tu seras contraint d'opérer directement la modification sur la base via un update et c'est mal !
    • [^] # Re: Soucis

      Posté par  (site Web personnel) . Évalué à 3.

      Moi ce que j'aimerais avoir un jour serait un pdo vraiment complet pour toutes les dbs (enfin pgsql/mysql/sqlite).Qu'on puisse appeler comme une classe.


      Il me semble que ce que tu décris est déjà implementé. En tout cas, dans mon framework Jelix, je récupère bien des objets avec PDO, et mieux encore, des objets qui sont instanciés avec la classe que je veux. (regarde PDOStatement::setFetchMode et les paramètres de PDOStatement::fetch() ;-) )

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n’en sommes pas responsables.