首頁 後端開發 php教程 使用 jbtronics/settings-bundle 的 Symfony 應用程式中的使用者可設定設定(部分遷移和環境變量

使用 jbtronics/settings-bundle 的 Symfony 應用程式中的使用者可設定設定(部分遷移和環境變量

Jul 19, 2024 am 11:26 AM

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

在本系列的前兩部分中,介紹了設定套件的基本概念以及如何使用它在 Symfony 應用程式中建立良好的使用者可設定設定。
在本部分中,您將了解如何對設定進行版本控制並在它們之間進行遷移。此外,您還將學習如何將環境變數與設定結合。

版本控制和遷移

隨著時間的推移,您的應用程式將會不斷發展,您的設定也會不斷發展。這意味著隨著時間的推移,新參數將添加到設定中,舊參數將被刪除,現有參數將被更改。為了解決這個問題,settings-bundle 提供了版本控制和遷移機制,它可以為您處理大部分工作。

假設您有一個像這樣的簡單設定類別:

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;
}
登入後複製

這些設定已經在您的應用程式中使用了一段時間,並且用戶已經將自訂設定保存到其中。如果您只想為設定新增參數,只需向類別新增屬性即可,這樣就可以正常運作。新參數將使用預設值進行初始化,用戶可以根據需要更改它:

#[Settings]
class TestSettings {

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

    #[SettingsParameter]
    public int $baz = 42;

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

登入後複製

刪除參數的工作方式類似。如果您從類別中刪除屬性,設定套件將忽略它的現有值,並在下次儲存設定時將其刪除。

但是,更棘手的是,如果您想重新命名字段,或者更複雜的是,更改其類型或資料的準確保存方式。為了不遺失使用者的現有自訂,您必須指定如何在設定的不同表示形式之間進行轉換。設定包可以透過提供遷移框架來支援您。

假設您想要以某種方式更改設定類,以便您現在可以擁有多個電子郵件地址。另外,您想要更改 baz 參數的索引,以便它不是從 0 開始,而是從 1 開始,這意味著所有現有值都應增加 1。最後您的設定類別應如下所示:

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;
}
登入後複製

測試設定類別現在具有新的預期結構,並且可以在應用程式中使用。但是,settings-bundle 不知道如何將現有資料轉換為新結構。這就是遷移的地方
開始發揮作用。

您可以看到settings屬性現在指定了version選項和migrationService選項:

版本選項指定設定的最新架構版本,且只是一個整數(大於零),每次變更設定類別的結構時都會遞增。您可以從 1 開始,並在每次更改設定類別的結構時遞增它。您可以將版本號碼直接放入屬性中,也可以為其定義常數,如範例所示,這樣做的好處是您可以輕鬆地從類別外部檢索當前版本。

第二個新東西是migrationService選項。這指定了實際執行資料遷移的服務類別。 migrationService 必須實作 SettingsMigrationInterface,它指定一個遷移函數,負責在兩個給定的資料版本之間執行遷移。

在大多數情況下,您希望在版本之間逐步遷移(意味著您遷移 1 -> 2,然後遷移 2 -> 3 等等,而不是直接遷移 1 -> 3 以避免程式碼重複)。在這種情況下,擴充 SettingsMigration 類別會更容易。使用這個抽象類,您的遷移服務可能如下所示:

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;
    }

}
登入後複製

遷移服務包含 migrateToVersionXX() 形式的各種方法,如果設定從版本 XX-1 遷移到版本 XX,類別會自動呼叫這些方法。此方法接收規範化形式的數據和設定類別的元數據,並且必須傳回規範化形式的數據,然後將其傳遞給參數類型轉換器。如果您想明確指定為哪個版本呼叫哪些函數,您可以重寫resolveStepHandler方法,該方法傳回要用於給定版本的閉包。

由於現有資料還沒有版本,所以假設是版本0。因此,當遇到這些資料settings-bundle時,會呼叫migrateToVersion1處理程序從0遷移到最新的版本1。

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;
}
登入後複製

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;
  }
}

登入後複製

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.

以上是使用 jbtronics/settings-bundle 的 Symfony 應用程式中的使用者可設定設定(部分遷移和環境變量的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1677
14
CakePHP 教程
1431
52
Laravel 教程
1334
25
PHP教程
1280
29
C# 教程
1257
24
說明PHP中的安全密碼散列(例如,password_hash,password_verify)。為什麼不使用MD5或SHA1? 說明PHP中的安全密碼散列(例如,password_hash,password_verify)。為什麼不使用MD5或SHA1? Apr 17, 2025 am 12:06 AM

在PHP中,應使用password_hash和password_verify函數實現安全的密碼哈希處理,不應使用MD5或SHA1。1)password_hash生成包含鹽值的哈希,增強安全性。 2)password_verify驗證密碼,通過比較哈希值確保安全。 3)MD5和SHA1易受攻擊且缺乏鹽值,不適合現代密碼安全。

PHP類型提示如何起作用,包括標量類型,返回類型,聯合類型和無效類型? PHP類型提示如何起作用,包括標量類型,返回類型,聯合類型和無效類型? Apr 17, 2025 am 12:25 AM

PHP類型提示提升代碼質量和可讀性。 1)標量類型提示:自PHP7.0起,允許在函數參數中指定基本數據類型,如int、float等。 2)返回類型提示:確保函數返回值類型的一致性。 3)聯合類型提示:自PHP8.0起,允許在函數參數或返回值中指定多個類型。 4)可空類型提示:允許包含null值,處理可能返回空值的函數。

PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

在PHP和Python之間進行選擇:指南 在PHP和Python之間進行選擇:指南 Apr 18, 2025 am 12:24 AM

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

PHP和Python:深入了解他們的歷史 PHP和Python:深入了解他們的歷史 Apr 18, 2025 am 12:25 AM

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

PHP和框架:現代化語言 PHP和框架:現代化語言 Apr 18, 2025 am 12:14 AM

PHP在現代化進程中仍然重要,因為它支持大量網站和應用,並通過框架適應開發需求。 1.PHP7提升了性能並引入了新功能。 2.現代框架如Laravel、Symfony和CodeIgniter簡化開發,提高代碼質量。 3.性能優化和最佳實踐進一步提升應用效率。

為什麼要使用PHP?解釋的優點和好處 為什麼要使用PHP?解釋的優點和好處 Apr 16, 2025 am 12:16 AM

PHP的核心優勢包括易於學習、強大的web開發支持、豐富的庫和框架、高性能和可擴展性、跨平台兼容性以及成本效益高。 1)易於學習和使用,適合初學者;2)與web服務器集成好,支持多種數據庫;3)擁有如Laravel等強大框架;4)通過優化可實現高性能;5)支持多種操作系統;6)開源,降低開發成本。

PHP的影響:網絡開發及以後 PHP的影響:網絡開發及以後 Apr 18, 2025 am 12:10 AM

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

See all articles