Maison développement back-end tutoriel php Paramètres configurables par l'utilisateur dans les applications Symfony avec jbtronics/settings-bundle (migrations de pièces et variables d'environnement

Paramètres configurables par l'utilisateur dans les applications Symfony avec jbtronics/settings-bundle (migrations de pièces et variables d'environnement

Jul 19, 2024 am 11:26 AM

User-configurable settings in Symfony applications with jbtronics/settings-bundle (Part  Migrations and environment variables

Dans les deux premières parties de cette série, les concepts de base du bundle de paramètres ont été introduits et comment l'utiliser pour créer de jolis paramètres configurables par l'utilisateur dans les applications Symfony.
Dans cette partie, vous apprendrez comment versionner vos paramètres et migrer entre eux. De plus, vous apprendrez à combiner des variables d'environnement avec des paramètres.

Gestion des versions et migration

Au fil du temps, votre application évoluera et vos paramètres également. Cela signifie qu'au fil du temps, de nouveaux paramètres seront ajoutés aux paramètres, les anciens seront supprimés et ceux existants seront modifiés. Pour gérer cela, le bundle de paramètres fournit un mécanisme de gestion des versions et de migration, qui s'occupe de la plupart du travail à votre place.

Supposons que vous ayez une classe de paramètres simple comme celle-ci :

namespace App\Settings;

use Jbtronics\SettingsBundle\Settings\Settings;
use Jbtronics\SettingsBundle\Settings\SettingsParameter;

#[Settings]
class TestSettings {

    #[SettingsParameter]
    public string $email = 'test@invalid';

    #[SettingsParameter]
    public int $baz = 42;
}
Copier après la connexion

Ces paramètres étaient déjà utilisés depuis un certain temps dans votre application et les utilisateurs y avaient déjà enregistré leurs personnalisations. Si vous souhaitez simplement ajouter un nouveau paramètre aux paramètres, vous pouvez le faire en ajoutant simplement une nouvelle propriété à la classe, et cela fonctionnera correctement. Le nouveau paramètre sera initialisé avec la valeur par défaut et les utilisateurs pourront le modifier à leur guise :

#[Settings]
class TestSettings {

    #[SettingsParameter]
    public string $email = 'test@invalid';

    #[SettingsParameter]
    public int $baz = 42;

    #[SettingsParameter]
    public bool $qux = true;
}

Copier après la connexion

La suppression d'un paramètre fonctionne de la même manière. Si vous supprimez une propriété de la classe, le bundle de paramètres ignorera les valeurs existantes et la supprimera la prochaine fois que les paramètres seront enregistrés.

Cependant, ce qui est plus délicat, c'est si vous souhaitez renommer un champ ou, plus complexe encore, modifier son type ou la manière exacte dont les données sont enregistrées. Pour ne pas perdre les personnalisations existantes des utilisateurs, vous devez spécifier comment convertir entre les différentes représentations des paramètres. Le bundle de paramètres peut vous aider en fournissant un cadre pour les migrations.

Supposons que vous souhaitiez modifier votre classe de paramètres de manière à ce que vous puissiez désormais avoir plusieurs adresses e-mail. De plus, vous souhaitez modifier l'indexation du paramètre baz, afin qu'il ne commence pas à 0, mais à 1, ce qui signifie que toutes les valeurs existantes doivent être incrémentées de 1. Au final, votre classe de paramètres devrait ressembler à ceci :

namespace App\Settings;

use Jbtronics\SettingsBundle\Settings\Settings;
use Jbtronics\SettingsBundle\Settings\SettingsParameter;

#[Settings(version: self::VERSION, migrationService: TestSettingsMigration::class)]
class TestSettings {

    public const VERSION = 1;

    #[SettingsParameter(type: ArrayType::class, options: ['type' => StringType::class])]
    public array $email = ['test@invalid'];

    #[SettingsParameter]
    //Now with different indexing
    public int $baz = 43;
}
Copier après la connexion

La classe des paramètres de test a désormais la nouvelle structure prévue et peut être utilisée dans l'application. Cependant, le bundle de paramètres ne saura pas comment convertir les données existantes vers la nouvelle structure. C'est là que les migrations
entre en jeu.

Vous pouvez voir que l'attribut settings a maintenant l'option version et l'option migrationService spécifiées :

L'option version spécifie la version de schéma la plus récente des paramètres et est simplement un nombre entier (plus grand zéro), qui est incrémenté à chaque fois que vous modifiez la structure de la classe de paramètres. Vous pouvez commencer par 1 et l'incrémenter à chaque fois que vous modifiez la structure de la classe de paramètres. Vous pouvez mettre le numéro de version directement dans l'attribut, ou vous pouvez définir une constante pour celui-ci, comme indiqué dans l'exemple, ce qui présente l'avantage de pouvoir récupérer facilement la version actuelle depuis l'extérieur de la classe.

La deuxième nouveauté est l'option migrationService. Ceci spécifie la classe de service qui effectue réellement la migration des données. Le migrationService doit implémenter SettingsMigrationInterface, qui spécifie une fonction de migration chargée d'effectuer la migration entre deux versions données des données.

Dans la plupart des cas, vous souhaitez effectuer des migrations par étapes entre les versions (ce qui signifie que vous migrez 1 -> 2, puis 2 -> 3 et ainsi de suite, au lieu de 1 -> 3 directement pour éviter la duplication de code). Dans cette situation, il est plus facile d’étendre la classe SettingsMigration. En utilisant cette classe abstraite, votre service de migration pourrait ressembler à ceci :

namespace App\Settings\Migrations;

use Jbtronics\SettingsBundle\Migrations\SettingsMigration;

class TestSettingsMigration extends SettingsMigration  {

    /**
     * This method is called automatically by the migration class and handles 
     * migration of version 0 (non versioned settings) to version 1.
     */
    public function migrateToVersion1(array $data, SettingsMetadata $metadata): array
    {

        /*
         * $data contains the old settings data, in the normalized form (in the way it was saved in the database)
         * Each key is the parameter name (not necessarily the property name) 
         * 
         * In the end we must return the new data in the normalized form, which is later then passed to 
         * the parameter type converters.
         */

        //If the email parameter was set, convert it to an array
        if (isset($data['email'])) {
            $data['email'] = [$data['email']];
        }

        //Increment the baz parameter, if it was set
        if (isset($data['baz'])) {
            $data['baz']++;
        }

        //Return the new data
        return $data;
    }

    /**
     * This method is called, to handle migration from version 1 to version 2.
     */
    public function migrateToVersion2(array $data, SettingsMetadata $metadata): array
    {
        //Perform some more migrations...

        return $data;
    }

}
Copier après la connexion

Le service de migration contient différentes méthodes sous la forme migrateToVersionXX(), qui sont appelées automatiquement par la classe si les paramètres sont migrés de la version XX-1 vers la version XX. La méthode reçoit les données sous forme normalisée et les métadonnées de la classe de paramètres et doit renvoyer les données sous forme normalisée, qui sont ensuite transmises aux convertisseurs de types de paramètres. Si vous souhaitez spécifier explicitement quelles fonctions sont appelées pour quelle version, vous pouvez remplacer la méthode solveStepHandler, qui renvoie la fermeture à utiliser pour une version donnée.

Comme les données existantes n'avaient pas encore de version, on suppose qu'il s'agissait de la version 0. Par conséquent, lorsqu'il rencontrera ces données, le bundle de paramètres appellera le gestionnaire migrateToVersion1 pour migrer de 0 vers la version 1 la plus récente.

The old data from the storage is passed to the migration method (as $data) and you have to convert it to the new form how it can be saved to storage and how the parameter type conversions can understand it. Each parameter is stored in the $data array with the parameter name as key. You can then modify the data as you like and return it in the end.

Please note that the $data array is in the normalized form, meaning that you only have simple datatypes like strings, integers, arrays and so on. If you want to like to work with the denormalized form (like objects, etc.) you might find the getAsPHPValue() and setAsPHPValue() methods available in the SettingsClass (or in the PHPValueConverterTrait) useful. Or you call the ParameterTypes you need directly.

The settings-bundle stores the version of the data in the storage provider, so that it is automatically known what version the data has and what migrations to perform. The migrations are automatically performed when trying to retrieve settings data (by getting the settings from the SettingsManager or calling a property of a lazy settings class). By default, the migrated data is written back to the storage after the migration, so that the migration only has to be performed once for each setting, even if the settings are not explicitly written back to the storage.

Environment variables

Environment variables are one of the classic possibilities to configure a Symfony application. They allow you for an easy configuration approach in automatic deployed applications, containers, etc. via a more or less unified interface. So they are pretty ideal for server administrators, who want to configure an application without touching the code. However, the big disadvantage of environment variables is, that they are not user-configurable, as users (even those intended as admin users) can not change them without direct access to the server.

To retain the advantages of environment variables, while also allowing users to configure the applications via the settings-bundle, the bundle can map environment variables to settings class parameters.

This is done via the envVar option on the SettingsParameter attribute:

#[Settings]
class TestSettings {

    #[SettingsParameter(envVar: 'APP_EMAIL')]
    public string $email = 'test@invalid';

    #[SettingsParameter(envVar: 'int:APP_BAZ', envVarMode: EnvVarMode::OVERWRITE)]
    public int $baz = 42;

    #[SettingsParameter(envVar: 'bool:APP_TEST_SETTINGS_QUX', envVarMode: EnvVarMode::OVERWRITE_PERSIST)]
    public bool $qux = true;
}
Copier après la connexion

The envVar option specifies the environment variable to map to the parameter. If it does not exist, nothing happens. However, if it exists, the bundle will retrieve the value of the environment variable and set it as the value of the parameter. By default, the "raw" environment variable contains just a string. If you have another simple data type (like an integer or a boolean), you can use one of Symfony's env var processors to convert the string value of the env variable to the desired type (e.g. int:APP_BAZ, which converts the content of APP_BAZ to an int).

The environment variable handling happens transparently in the background, meaning that you can use the settings class as usual, and you (almost) do not have to care about the environment variables when using the settings.

Environment variable handling modes

The envVarMode option specifies how the environment variable should be handled. If no mode is specified, the mode EnvVarMode::INITIAL is used. In this mode the environment variable is only used to initialize the parameter. That means if the parameter is used the first time, instead of the default value in the code, the value of the environment variable is used. Users can change this value as they like, and the environment variable will not affect the parameter anymore. This mode allows a server administrator to set useful initial defaults via environment variables (e.g. while deploying the container), but users can change them completely later.

However, in some cases, you might want the server admin to enforce a certain value via environment variables and forbid users to change them via WebUI. For these cases, you can use the EnvVarMode::OVERWRITE and EnvVarMode::OVERWRITE_PERSIST mode. In this mode, the environment variable will always overwrite a parameter value, no matter what was set as a value before by users. This means that freshly retrieved settings will always have the value of the environment variable, even if the user changed it before. The OVERWRITE_PERSIST mode additionally writes the value back to the storage, so that the value is still set even after the env variable is removed (however users can then change the value again).

If a parameter is overwritten by an environment variable, its form field will be disabled in the default generated WebUI, so that users can see that the value is enforced by the environment variable and can not be changed via the WebUI.

A limitation of this system is that you can still change the value of a settings parameter in your code, even if it is overwritten by an environment variable. The changes will also be used in other parts of the application during the request. It is just that these changes do not get persisted, meaning that if you reload the settings from the storage, the value of the environment variable will be used again. If you try to change settings parameters via direct access in you code, you might want to check if the parameter is overwritten by an environment variable (by using the isEnvVarOverwritten method of the SettingsManager), and if so, you might want to disable the possibility to change the parameter in your code.

Environment variables mapper

For many constellations, the type conversion via the env var processor works fine. However, in some cases where you have more complex parameter types, you need a more complex conversion logic. For these cases, you can use the envVarMapper option of the SettingsParameter attribute. This option specifies a callable, which is called with the value of the environment variable and must return the value to set as the parameter value:

class TestSettings {

  #[SettingsParameter(envVar: 'string:ENV_VAR3', envVarMapper: [self::class, 'mapDateTimeEnv'])
  private ?\DateTime $dateTimeParam = null;

  public static function mapDateTimeEnv(?string $value): ?\DateTime
  {
    return $value ? new \DateTime($value) : null;
  }
}

Copier après la connexion

The $value parameter passed, is the value retrieved from the environment variable, with env var processors applied, meaning that it not necessarily has to be a string.

Conclusion

You can see that jbtronics/settings-bundle can support you with handling changes in the schema of settings, and how to map environment variables to settings parameters. This allows you to have a flexible configuration system, which can be used by users and server administrators alike.

As always you can find more information in the bundle documentation.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

<🎜>: Grow A Garden - Guide de mutation complet
3 Il y a quelques semaines By DDD
<🎜>: Bubble Gum Simulator Infinity - Comment obtenir et utiliser les clés royales
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Système de fusion, expliqué
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers of the Witch Tree - Comment déverrouiller le grappin
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Tutoriel Java
1670
14
Tutoriel PHP
1274
29
Tutoriel C#
1256
24
Expliquez le hachage de mot de passe sécurisé dans PHP (par exemple, Password_Hash, Password_verify). Pourquoi ne pas utiliser MD5 ou SHA1? Expliquez le hachage de mot de passe sécurisé dans PHP (par exemple, Password_Hash, Password_verify). Pourquoi ne pas utiliser MD5 ou SHA1? Apr 17, 2025 am 12:06 AM

Dans PHP, Password_Hash et Password_verify Les fonctions doivent être utilisées pour implémenter le hachage de mot de passe sécurisé, et MD5 ou SHA1 ne doit pas être utilisé. 1) Password_hash génère un hachage contenant des valeurs de sel pour améliorer la sécurité. 2) Password_verify Vérifiez le mot de passe et assurez-vous la sécurité en comparant les valeurs de hachage. 3) MD5 et SHA1 sont vulnérables et manquent de valeurs de sel, et ne conviennent pas à la sécurité de mot de passe moderne.

PHP et Python: comparaison de deux langages de programmation populaires PHP et Python: comparaison de deux langages de programmation populaires Apr 14, 2025 am 12:13 AM

PHP et Python ont chacun leurs propres avantages et choisissent en fonction des exigences du projet. 1.Php convient au développement Web, en particulier pour le développement rapide et la maintenance des sites Web. 2. Python convient à la science des données, à l'apprentissage automatique et à l'intelligence artificielle, avec syntaxe concise et adaptée aux débutants.

PHP en action: Exemples et applications du monde réel PHP en action: Exemples et applications du monde réel Apr 14, 2025 am 12:19 AM

PHP est largement utilisé dans le commerce électronique, les systèmes de gestion de contenu et le développement d'API. 1) E-commerce: Utilisé pour la fonction de panier et le traitement des paiements. 2) Système de gestion du contenu: utilisé pour la génération de contenu dynamique et la gestion des utilisateurs. 3) Développement des API: Utilisé pour le développement de l'API RESTful et la sécurité de l'API. Grâce à l'optimisation des performances et aux meilleures pratiques, l'efficacité et la maintenabilité des applications PHP sont améliorées.

Comment fonctionne la résistance au type PHP, y compris les types scalaires, les types de retour, les types d'union et les types nullables? Comment fonctionne la résistance au type PHP, y compris les types scalaires, les types de retour, les types d'union et les types nullables? Apr 17, 2025 am 12:25 AM

Le type PHP invite à améliorer la qualité et la lisibilité du code. 1) Conseils de type scalaire: Depuis PHP7.0, les types de données de base sont autorisés à être spécifiés dans les paramètres de fonction, tels que INT, Float, etc. 2) Invite de type de retour: Assurez la cohérence du type de valeur de retour de fonction. 3) Invite de type d'union: Depuis PHP8.0, plusieurs types peuvent être spécifiés dans les paramètres de fonction ou les valeurs de retour. 4) Invite de type nullable: permet d'inclure des valeurs nulles et de gérer les fonctions qui peuvent renvoyer les valeurs nulles.

La pertinence durable de PHP: est-elle toujours vivante? La pertinence durable de PHP: est-elle toujours vivante? Apr 14, 2025 am 12:12 AM

PHP est toujours dynamique et occupe toujours une position importante dans le domaine de la programmation moderne. 1) La simplicité de PHP et le soutien communautaire puissant le rendent largement utilisé dans le développement Web; 2) sa flexibilité et sa stabilité le rendent exceptionnelle dans la gestion des formulaires Web, des opérations de base de données et du traitement de fichiers; 3) PHP évolue et optimise constamment, adapté aux débutants et aux développeurs expérimentés.

PHP et Python: différents paradigmes expliqués PHP et Python: différents paradigmes expliqués Apr 18, 2025 am 12:26 AM

PHP est principalement la programmation procédurale, mais prend également en charge la programmation orientée objet (POO); Python prend en charge une variété de paradigmes, y compris la POO, la programmation fonctionnelle et procédurale. PHP convient au développement Web, et Python convient à une variété d'applications telles que l'analyse des données et l'apprentissage automatique.

Comment empêchez-vous l'injection SQL en PHP? (Déclarations préparées, APD) Comment empêchez-vous l'injection SQL en PHP? (Déclarations préparées, APD) Apr 15, 2025 am 12:15 AM

L'utilisation de déclarations de prétraitement et l'APD dans PHP peut effectivement empêcher les attaques d'injection SQL. 1) Utilisez PDO pour vous connecter à la base de données et définir le mode d'erreur. 2) Créez des instructions de prétraitement via la méthode de préparation et transmettez des données à l'aide des espaces réservés et exécutez des méthodes. 3) Traitez les résultats de la requête et assurez la sécurité et les performances du code.

PHP et Python: exemples de code et comparaison PHP et Python: exemples de code et comparaison Apr 15, 2025 am 12:07 AM

PHP et Python ont leurs propres avantages et inconvénients, et le choix dépend des besoins du projet et des préférences personnelles. 1.Php convient au développement rapide et à la maintenance des applications Web à grande échelle. 2. Python domine le domaine de la science des données et de l'apprentissage automatique.

See all articles