Préfixer ses tables en base de données est un geste simple aux multiples avantages, que nous allons découvrir plus bas. Si, dans wordpress, il est simplissime de changer le préfixe d'origine (le fameux "wp_
"), c'est autrement plus laborieux dans symfony.
Vous avez choisi de faire un projet avec Symfony ? Bon choix ! Vous codez, tout se passe bien, et voici l'heure de mettre en prod… Votre hébergement, mutualisé, ne vous permet pas de créer une nouvelle base, mais seulement des tables dans la BDD associée. Et là, erreur, la table users existe déjà...
Pourquoi préfixer ses tables ?
Ajouter un préfixe à ses tables a de nombreux avantages. Tout d'abord, pour la sécurité. En effet, une table users, tous les sites du monde en ont une. En cherchant une faille de sécurité, on risque de pouvoir facilement accéder à cette table, même sans connaitre l'arborescence du projet, si elle a un nom trop courant. Et c'est un argument valable même si on peut avoir autant de base de données qu'on veut (soit une par projet) : préfixer ses tables sera toujours un gain non négligeable sur le plan de la sécurité.
Ensuite, si vous êtes sur des petits projets, que vous utilisez un hébergement mutualisé, ou que sais-je encore, qui vous contraint à n'avoir qu'une base de données pour tous vos sites, Préfixer ses tables est indispensable. Cela permet de différencier des tables qui auraient le même nom (users et users, par exemple...), en leur ajoutant un préfixe propre à chaque projet. Ainsi, nous aurions ck_users et bk_users, pour des sites comme cooking et booking par exemple. Plus de confusion possible, plus de risques d'agir sur les mauvaises tables.
Enfin, pour un travail de maintenance et de sauvegarde, le jour où vous avez besoin de faire une sauvegarde ou de réinstaller les tables d'un projet, pouvoir les sélectionner grâce à un préfixe commun est un énorme atout : plus de risques d'oublis, ou au contraire d'associer des tables d'un autre projet à votre sauvegarde...
Bref, c'est une très bonne hygiène de travail, tant sur les plans technique, sécuritaire et pratiques !
Comment ajouter un préfixe ?
Rentrons dans le vif du sujet. Si vous utilisez symfony, vous savez que vous avec un environnement de test compris. Vous savez aussi que lorsque vous créez votre base de données de test, automatique, elle est suffixée de _test
.
S'il existe un dbname_suffix
, on doit avoir un dbname_prefix
? ou un dbtablename_prefix
? Et bien non, ce serait trop simple ! 😉
La solution la plus sale serait de renommer toutes nos entités, en leur incorporant, dans le code, le préfixe. Vous imaginez le bazar, si vous pensez à celà à la fin de votre projet ? Et même si vous êtes consciencieux et que vous le mettez en place dès le début, ça va alourdir le code et rendre sa lecture et sa compréhension d'autant plus difficile.
Non, Il va falloir entrer plus en avant pour pouvoir ajouter notre fonctionnalité.
Le principe des services
Un service, c'est un bout de code (généralement un objet), qui réalise une action. Pour appeler ce code et l'exécuter à des moments précis, on lui associe une configuration.
En gros, tout ce qu'on serait amené à faire plusieurs fois à des endroits différents du code peut être transformé en un service. C'est une factorisation, qui permet d'alléger le code et de mieux s'y retrouver.
Création du service de préfixe
Commençons donc par créer ce fameux service. La documentation de doctrine (qui n'est rien d'autre qu'un service, soit dit en passant) nous aide sur ce point :
Dans un fichier qu'on rangera dans un dossier Services et qu'on appelera DatabaseTablePrefix.php, on mettra ce code :
Configurer le service
Une fois ce code enregistré, il faut mettre en place la configuration associée.
Dans le fichier config/services.yaml
, on met ce code :
Attention à l'indentation, c'est très important de bien revenir aux bonnes lignes au bon moment. Dans ce code, on dit à symfony qu'il faut appeler notre service à chaque fois que doctrine est appelé. Et on en profite pour lui dire que nous stockerons la valeur de notre variable $prefix
dans notre fichier .env
. C'est un choix que j'ai fait pour tout regrouper au même endroit. Bien sûr, on aurait pu lui donner sa valeur ici. Mais puisque dans le .env
nous avons toutes les infos concernant la BDD, autant y ranger le préfixe aussi non ?
Définir le préfixe dans le .env
Et donc, pour finir, il faut aller dans le .env
pour donner la valeur de notre préfixe :
Évidemment, vous remplacerez "prefix
" par ce que vous voulez.
Conclusion
Et voilà, si vous faites votre migration, vous verrez que dans votre base de données, toutes vos tables sont bien préfixées, et que cela ne change rien à l'exécution de votre code !
Mieux encore : cela est pris en compte quelque soit votre environnement de travail : local, prod, test... Toutes vos tables seront préfixées de la même manière, ce qui est important pour un soucis de cohérence.
A l'exception d'une table (il faut toujours des exceptions) : la table messenger_messages
qui est gérée par symfony, ne prend pas de préfixe. Allez savoir pourquoi, c'est un mystère.
Si vous connaissez la réponse à cette énigme, n'hésitez pas à la proposer dans les commentaires !