Download the PHP package jemdev/dbrm without Composer

On this page you can find all versions of the php package jemdev/dbrm. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package dbrm

jemdev\dbrm : DataBase Relational Mapping


Installation

Avec Composer, ajouter ce qui suit dans la partie require de votre composer.json:


Présentation et principe de fonctionnement.

Ce package permet un accès aux données d'une base de données relationnelle. L'idée fondatrice part du principe qu'on peut faire des lectures sur des tables multiples mais que l'écriture ne peut se faire que sur une seule table à la fois. Par conséquent, il devenait envisageable de créer des objets dynamiques pour chacune des tables sur lesquelles on souhaitait effectuer des opérations en écriture.

Des méthodes relativement simples permettent d'exécuter des requêtes préparées pour la collecte de données. Pour l'écriture, d'autres méthodes permettent de créer une instance pour initialiser une ligne d'une table donnée et d'affecter les valeurs souhaitées aux différentes colonnes de la table pour cette ligne. Selon que l'identifiant de la ligne est fourni ou non, l'écriture sera une création ou une modification, voire une suppression.

Pour pouvoir créer ces instances dynamiques, un système permet d'établir une sorte de cartographie du schéma de données, détaillant la liste des tables, des tables relationnelles et des vues qui sont présentes. Sur la base de ces informations, une instance pour une table donnée définit les propriétés en lisant la liste des colonnes, leur types et d'autres informations pratiques.

Lors de la connexion, si le fichier de configuration n'existe pas, il est automatiquement créé. Par la suite, si on modifie la structure du schéma, même si ce n'est que pour ajouter, modifier ou retirer une colonne dans une table, une méthode permet de régénérer ce fichier de configuration. Il m'est apparu comme très peu pratique de devoir créer une classe pour chacune des tables, ces modifications de structure induisant la ré-écriture partielle de certaines de ces classes à chaque fois. Ces classes sont donc gérées dynamiquement et sont, en réalité, des classes virtuelles.

Récupérer un objet de connexion

Configurer la connexion

Il est impératif de créer un fichier contenant les paramètres de connexion au SGBDR. Ce fichier doit être nommé dbCnxConf.php et être formaté de la manière suivante :

Les types de SGBDR supportés

À ce jour, ce n'est utilisable qu'avec MySQL et PostGreSQL. Je n'ai pas testé avec les forks de MySQL autres que MariaDb (percona et autres) mais dans la mesure où ils sont compatibles, ça ne devrait pas présenter de blocage. La valeur à utiliser pour la variable $db_app_type :

Ce fichier devra être placé dans le répertoire où sont situés vos éventuels autres fichiers de configuration selon l'architecture de votre application. Il conviendra par la suite de pouvoir fournir en temps voulu le chemin absolu vers ce fichier. Dès le départ, s'il n'existe pas, un autre fichier de configuration sera généré automatiquement et sera indispensable au bon fonctionnement du package. Ce fichier sera généré en deux version, le premier nommé dbConf.php pourra être assez facilement lu par n'importe quel développeur, le second qui sera privilégié pour l'utilisation par l'application sera nommé dbConf_compact.php et correspondra strictement au même contenu mais compacté et ramené sur une seule ligne. Ce fichier décrit en détail l'ensemble de la structure de données, tables, tables relationnelles et vues, colonnes, clés et autres informations détaillées. Il sera utilisé par les objets destinés à toutes les opérations en écriture, insertion, mises à jour ou suppression.

Méthodes globales accessibles

Deux méthodes de base seront indispensables :

Deux autres méthodes nous intéressent principalement ici et ne seront utilisées que lorsqu'on devra enregistrer des création ou modifications de données :

Une autre méthode pourra se révéler pratique lors de la phase de développement de votre application :

Lecture de données

Il n'y a pas de générateur de requêtes, à tout le moins pour l'instant. On devra écrire soi-même les requêtes en lecture qui devront être exécutées pour la collecte de données.

Chaque requête peut être paramétrée, et sera exécutée avec PDO : elle retournera une donnée unique, une ligne de données ou bien un tableau de données voire même un objet. On s'appuiera sur une instance de la classe jemdev\dbrm\vue qu'on définira au préalable.

Exemple : par convention, l'instance de connexion sera la variable « $oVue » et aura été définie en amont (entendez le mot de « vue » au sens SQL du terme).

Note:

Le nom de l'objet $oVue dans cet exemple n'est pas anodin, il faut entendre le mot vue au sens SQL du terme. Une vue dans une base de données est une synthèse d'une requête d'interrogation de la base. On peut la voir comme une table virtuelle, définie par une requête.

Les méthodes accessibles

Le nom des méthodes est inspiré de celles qu'on emploie avec l'extension MySQL. Le retours sont bien entendu similaires dans leur forme.

Écriture de données

Les méthodes accessibles

Sur une instance donnée, vous disposez des méthodes suivantes :

Mise en pratique

On écrit des données, comme mentionné en introduction, que sur une seule table à la fois. Pour ce faire, on crée un objet représentant une ligne de ladite table. Voici d'abord un exemple schématique : Les tables sur lesquelles s'appuient notre exemple auront la forme suivante :

  1. Table t_interlocuteur_int

  2. Table t_adresse_adr

Note importante : vous ne pourrez pas définir vous-même la valeur de la clé primaire en insérant une nouvelle ligne de données. Cette valeur sera générée automatiquement par le SGBD si cette colonne est bien en auto-increment (MySQL et certains SGBDR. Pour d'autres comme Oracle qui ne disposent pas de cette fonctionnalité, il sera avisé de mettre en place pour chaque table une séquence et un trigger before insert pour générer la clé primaire automatiquement). Lorsqu'on initialise une ligne de données, on peut en option indiquer la valeur de cette clé primaire si on la connaît : le cas échéant, les colonnes seront alors alimentées avec les valeurs correspondant à cette ligne, sinon, nous aurons une ligne vide prête à compléter. À présent, écrivons une ligne de données :

Les erreurs possibles

Lors de l'insertion des données, une vérification est automatiquement effectuée. Si une colonne requiert obligatoirement une valeur et qu'aucune n'est envoyée, une eexception sera levée. Le type de donnée sera également vérifié et selon le cas, une exception pourra être levée si une donnée n'est pas conforme au modèle de données défini.

En résumé : l'instance d'une table

Lorsque vous créez une instance pour une table donnée, chaque colonne de cette table devient une propriété de cette instance. Ainsi, la colonne int_nom est une propriété de l'objet $oInterlocuteur et peut donc être invoquée comme une propriété publique de l'objet. Si vous essayez d'affecter une valeur sur une colonne qui n'existe pas dans la table considérée, une exception sera levée. De même que vous ne pourrez pas affecter une valeur arbitraire sur une clé primaire. Cependant, il existe un cas où vous pourrez définir vous-même la valeur d'une clé primaire lorsqu'il s'agit d'une clé composite sur une table relationnelle. Ainsi, si au lieu d'un lien direct entre interlocuteur et adresse dans notre exemple nous avions eu une table relationnelle entre les deux, par exemple r_int_has_adr_iha, nous aurions les colonnes int_id et adr_id composant la clé primaire de cette table relationnelle. Dans un tel cas, nous modifierons le code précédent dans la manière suivante:

Et là, pas de blocage lors de l'affectation des valeurs pour la clé primaire.

En pratique

Une utilisation pratique vous amènera sans doute à répartir les requêtes en écriture sur différentes tables dans différentes fonctions/méthodes appelées à partir d'un endroit unique, ce qui vous permettra d'utiliser au besoin le mode transactionnel. En démarrant la transaction au départ, vous exécutez chaque enregistrement, et si une des méthodes retourne FALSE à cause d'une erreur, vous pourrez interrompre la succession des enregistrements et terminer la transaction par un ROLLBACK, évitant ainsi de pourrir vos tables avec des données orphelines ou incohérentes.

Ce qu'on ne peut pas faire (pour l'instant)

Actuellement, il reste quelques éléments en TODO-LIST et en particulier, lors de l'écriture de données, la possibilité d'affecter non pas une valeur mais un appel de fonction SQL. Supposons par exemple que vous vouliez utiliser une fonction de chiffrement intégrée de MySQL pour affecter une valeur. Il n'est pour l'instant pas possible de faire ceci :

Comment contourner le problème.

Pour une utilisation quotidienne, ce n'est pas un réel problème, ce type de cas particulier étant relativement rare. Si cependant vous devez pouvoir effectuer une telle opération, vous avez deux options.

La suite du code ne change pas.

Une instance = une ligne

Il n'a pas été prévu pour l'instant de pouvoir effectuer une mise à jour ou encore une suppression de lignes multiples dans la mesure où une mise à jour s'effectuera uniquement en fonction de la valeur d'une clé primaire. Pratiquant l'utilisation au quotidien de ce package depuis déjà de nombreuses années et ce sur une application de gestion, je n'ai en réalité jamais eu besoin d'implémenter cette possibilité. Et pour les rares fois où ça doit se produire, je peux contourner ce manque en collectant la liste des clé primaires à prendre en compte dans une mise à jour et chaque ligne sera traitée individuellement dans une boucle.


Temps d'exécution des requêtes

Ce petit système s'appuie sur la méthode native error_log de PHP pour la journalisation de requêtes lentes. Au fil du développement d'une application, il peut être utile d'identifier des goulets d'étranglement qui ralentissent l'application. On peut alors simplement activer un système de mesure qui effectuera un chronométrage systématique de toutes les requêtes. On paramètre le système en lui indiquant :

La mise en oeuvre est très simple, exemple :

C'est tout : une fois ceci lancé, il suffit alors de naviguer normalement dans l'application, spécialement dans les parties qui affichent des ralentissements apparents, puis de vérifier le fichier journal pour y trouver éventuellement des requêtes qui devraient alors être optimisées pour une accélération.

Pour le mode « fichier », si le fichier n'existe pas, il sera créé.

Une gestion de cache dynamique

Un problème d'accès à la configuration du serveur MySQL sur lequel je travaillais m'interdisait de paramétrer le cache intégré et même tout simplement de l'activer par défaut. Souhaitant pouvoir disposer d'un système de gestion de cache de requêtes, j'ai ajouté des classes permettant de gérer cet aspect.

Globalement, chaque requête en lecture peut, si le cache est activé, stocker le résultat en cache sur fichier voire même sur MemCache si cette extension est activée. Toute écriture sur une des table va régénérer le cache pour les requêtes où est impliquée la table en question. La durée de vie du cache est donc fonction de l'exécution de nouvelles écritures et non d'une durée de vie pré-définie. Si le résultat d'une requête est valide pendant trois minutes et qu'une écriture intervient, le cache est renouvelé, si ce même résultat est toujours valide après trois semaines, il est parfaitement inutile de le régénérer.

Certaines méthodes permettent de régénérer manuellement le cache pour certaines tables. Par exemple, si lors d'une écriture sur une table un trigger va déclencher l'exécution d'une procédure stockée créant des écritures sur d'autres tables, il sera important de régénérer le cache sur ces autres tables. Il n'est pas possible de détecter ces écritures en PHP dans la mesure où c'est le SGBDR qui gère ça directement. De même si des tâches CRON déclenchent des écritures sans passer par PHP, il n'est pas possible d'intercepter cette information pour mettre à jour le cache correspondant, il conviendra donc d'écrire un code PHP qui effectuera ce nettoyage, code qui devra être exécuté dans une tâche à ajouter au CronTab.

Par défaut, le cache n'est pas activé, et si vous avez la possibilité de gérer le cache intégré de votre SGBDR, ce sera alors une solution préférable et plus performante.

Intégration avec Symfony

Pour ceux désirant travailler avec Symfony et accéder aux données d'une base sans recourir à Doctrine, cette solution présente une alternative viable, quoique peut-être plus exigeante techniquement. Ici, pas question de pouvoir modifier la structure de la base de données avec cette librairie : ça relève du DBA et il est hors de question qu'un développeur touche à cette structure. Cependant, le système même de jemdev\dbrm permet les évolution de la structure de données et un fichier de configuration doit pouvoir être généré. Le système de ligne de commandes dans Symfony se révèle pour celà fort pratique. Nous allons donc voir ici comment générer ce fichier d'une seule ligne de commande.

Note : ce qui suit n'est qu'une suggestion qui fonctionne mais que vous pouvez vouloir implémenter autrement.

Les fichiers de configuration

Dans le répertoire /config de l'application Symfony, nous allons créer un sous-répertoire dans /config/packages que nous nommerons /dbrm.

Dans ce nouveau répertoire, nous allons créer deux fichiers de base, appConf.php et dbConf.php, et nous inscrirons des éléments de base pour rendre le système de configuration opérationnel.

Le fichier appConf.php

C'est pour l'instant tout ce dont nous avons besoin dans ce fichier.

Le fichier dbConf.php

Ce fichier est normalement généré par une des librairies du package, mais en fournissant le squelette de base, nous allons simplifier les choses.

Ne modifiez rien dans cette base. Et par la suite, ne modifiez jamais manuellement ce fichier.

Mise en place de la commande

Dans notre classe, nous avons défini un nom pour la commande, « app:dbrmconf ».

Ouvrons maintenant une console et, après nous être placés dans le répertoire de l'application, créons la commande :

Si tout s'est correctement déroulé, vous verrez alors s'afficher ce qui suit :

Une classe a donc été créée dans le répertoire /src/Command, nous allons y apporter quelques modifications. Éditons cette classe.

Configuration de la classe de commande

Voici le code nécessaire :

La méthode DbrmconfCommand::execute va lancer l'exécution de la méthode DbrmconfCommand::resetDbConf que nous avons ajoutée, et le fichier de configuration vu plus haut dbConf.php va être régénéré selon les informations collectées dans la base de données.

Vérifions l'existence de cette nouvelle commande en demandant la liste des commandes existantes mais en limitant au namespace app :

Le résultat normal devrait comporter ceci :

Et nous voyons bien en bas notre nouvelle commande assortie du message informant de la nature de cette commande tel que nous l'avons défini dans notre nouvelle classe.

Essayons ça :

Si tout s'est correctement déroulé, vous devriez voir ceci :

Tel que nous l'avons également défini dans notre classe de commande, dans la méthode execute.

Attention, jemdev\dbrm n'est PAS Doctrine

Ce package ne remplacera jamais Doctrine, ce n'est pas un ORM. Il permet de collecter des données, de les modifier ou de les supprimer. Mais il ne permet pas de modifier la structure des données, ni de générer des formulaires pré-remplis et autres fonctionnalités exotiques du même genre. Il n'impose pas non plus de faire usage d'une sorte de langage bâtard entre le PHP et le SQL : si vous n'avez pas une maîtrise de base du langage SQL, alors gardez Doctrine.


Conclusion

Ce package se veut simple d'utilisation de façon à ne pas perdre le développeur dans les complications de l'implémentation, et ce sans avoir à se préoccuper du type de serveur de base de données utilisé, que ce soit MySQL/MariaDb, ou PostGreSQL.

À venir

Il reste à développer le code qui permettra d'utiliser des SGBDR autres que MySQL ou PostGreSQL, codes qui pour l'instant n'existent pas. Il s'agit de pouvoir construire le tableau de configuration d'un schéma de données. MySQL et PostGreSQL implémentent INFORMATION_SCHEMA, ce qui facilite grandement ce travail, mais tous les SGBDR ne l'implémentent pas, comme par exemple Oracle. Il existe cependant d'autres manière de collecter ces informations pour aboutir au même résultat.

Par la suite, le fonctionnement s'appuyant sur PDO, l'intégration de jemdev\dbrm pourra se faire dans n'importe quel projet.

Les projets à plus long terme

L'idée d'un générateur de requêtes automatisé flotte dans l'air depuis pas mal de temps mais requiert un niveau de connaissances en mathématiques que je n'ai malheureusement pas. Il est question de s'appuyer sur la théorie des graphes pour déterminer quelles jointures devront être établies pour n'avoir à définir que les colonnes de telle ou telle table est attendue pour que le moteur construise automatiquement le chemin approprié. Le fichier de configuration permet d'ores et déjà de créer une matrice (le code n'est pas intégré dans le package mais est déjà prêt et opérationnel), il reste à définir l'algorithme approprié de façon à construire des requêtes respectant les standards les plus exigeants.

Toute contribution en la matière sera bienvenue.


All versions of dbrm with dependencies

PHP Build Version
Package Version
Requires php Version >=5.4.0
hoa/registry Version ~3.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package jemdev/dbrm contains the following files

Loading the files please wait ....