lamoda / multi-env
提供类以在多租户环境中处理环境变量的库
1.0.0
2022-10-14 13:06 UTC
Requires
- php: ^7.4 || ^8.0
- ulrichsg/getopt-php: ^4.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ~v3.12.0
- phpunit/phpunit: ^9.5
- vlucas/phpdotenv: v3.6.10
Suggests
- vlucas/phpdotenv: Required for DotEnvFileReaderAdapter
README
提供类以在多租户环境中处理环境变量的库
基于初始化阶段传递给它的参数的库将决定当前请求应使用哪个环境变量。
安装
- 使用composer安装库
composer require lamoda/multi-env
使用
在非多租户环境中使用库的示例(在开发模式下可能很有用)
<?php use \Lamoda\MultiEnv\Strategy\RawEnvResolvingStrategy; use \Lamoda\MultiEnv\Decorator\EnvProviderDecorator; // RawEnvResolvingStrategy - just wrap native PHP get_env function call $strategy = new RawEnvResolvingStrategy(); EnvProviderDecorator::init($strategy); // Will be search original TEST_ENV env variable EnvProviderDecorator::getEnv('TEST_ENV');
在多租户环境中使用库的示例
<?php use \Lamoda\MultiEnv\Strategy\HostBasedEnvResolvingStrategy; use \Lamoda\MultiEnv\Strategy\FileBasedEnvResolvingStrategy; use \Lamoda\MultiEnv\Decorator\EnvProviderDecorator; /* * Pass as first param one of available HostDetectorInterface implementations * Pass as second param one of available EnvNameFormatterInterface implementations */ $strategy = new HostBasedEnvResolvingStrategy($hostDetector, $envFormatter); EnvProviderDecorator::init($strategy); /* * Will search env with some specific prefix/suffix resolved by HostDetectorInterface * For example host_id__TEST_ENV */ EnvProviderDecorator::getEnv('TEST_ENV'); /* * Pass as first param one of available HostDetectorInterface implementations which detect HostId for current request * Pass as second param one of available EnvFileReaderInterface (for now available only DotEnvV2FileReaderAdapter) which load specific env file * Pass as third param another EnvResolvingStrategy which find specific env variable from loaded envs */ $strategy = new FileBasedEnvResolvingStrategy($hostDetector, $envFileReader, $envResolvingStrategy); EnvProviderDecorator::init($strategy); EnvProviderDecorator::getEnv('TEST_ENV');
使用内置工厂设置的库
- 为在不同目录存储的文件中的环境设置库
<?php use \Lamoda\MultiEnv\Builder\FileBasedEnvResolvingStrategyBuilder; use \Lamoda\MultiEnv\Decorator\EnvProviderDecorator; /* * Result strategy resolve hostId from server headers or cli args * Then load all envs from .env file stored by path /var/envs/*hostId* * Read TEST_ENV env variable */ $strategy = FileBasedEnvResolvingStrategyBuilder::buildStrategy('HTTP_X_HOST_ID', 'host_id', '.env', '/var/envs'); EnvProviderDecorator::init($strategy); EnvProviderDecorator::getEnv('TEST_ENV');
- 为带有前缀的环境设置库
<?php use \Lamoda\MultiEnv\Builder\HostBasedEnvResolvingStrategyBuilder; use \Lamoda\MultiEnv\Decorator\EnvProviderDecorator; /* * Result strategy resolve hostId from server headers or cli args * Add prefix to original env name. Result be like *hostId*___TEST_ENV * Replace all '-' char to '_' case '-' illegal in env variable name * Read *host_id*___TEST_ENV env variable */ $strategy = HostBasedEnvResolvingStrategyBuilder::buildStrategy('HTTP_X_HOST_ID', 'host_id', '___'); EnvProviderDecorator::init($strategy); EnvProviderDecorator::getEnv('TEST_ENV');
使用多种策略设置的库
<?php use \Lamoda\MultiEnv\Strategy\FirstSuccessfulEnvResolvingStrategy; use \Lamoda\MultiEnv\Strategy\RawEnvResolvingStrategy; use \Lamoda\MultiEnv\Strategy\HostBasedEnvResolvingStrategy; use \Lamoda\MultiEnv\HostDetector\FirstSuccessfulHostDetector; use \Lamoda\MultiEnv\HostDetector\CliArgsBasedHostDetector; use \Lamoda\MultiEnv\HostDetector\ServerHeadersBasedHostDetector; use \Lamoda\MultiEnv\Formatter\PrefixAppendFormatter; use \Lamoda\MultiEnv\HostDetector\Factory\GetOptAdapterFactory; use \Lamoda\MultiEnv\Decorator\EnvProviderDecorator; $rawEnvResolvingStrategy = new RawEnvResolvingStrategy(); $hostBasedEnvResolvingStrategy = new HostBasedEnvResolvingStrategy( new FirstSuccessfulHostDetector([ new ServerHeadersBasedHostDetector('HTTP_X_TEST_HEADER'), new CliArgsBasedHostDetector('host_id', GetOptAdapterFactory::build()) ]), new PrefixAppendFormatter('___') ); $firstSuccessfulStrategy = new FirstSuccessfulEnvResolvingStrategy([ $rawEnvResolvingStrategy, $hostBasedEnvResolvingStrategy ]); EnvProviderDecorator::init($firstSuccessfulStrategy); /* * Try find original env 'TEST_ENV' first. * If original env not found than try to find env with some specific prefix/suffix resolved by HostDetectorInterface. * For example host_id__TEST_ENV */ EnvProviderDecorator::getEnv('TEST_ENV');
可用的HostDetectorInterface实现
-
\Lamoda\MultiEnv\HostDetector\ServerHeadersBasedHostDetector - 使用HTTP请求来识别主机
<?php use \Lamoda\MultiEnv\HostDetector\ServerHeadersBasedHostDetector; use \Lamoda\MultiEnv\HostDetector\Exception\HostDetectorException; /* * Search passed needle in $_SERVER header. Use found value to identify current host * Throw HostDetectorException when passed empty needle */ $headerBasedHostDetector = new ServerHeadersBasedHostDetector('HTTP_X_SOME_HEADER'); $hostId = $headerBasedHostDetector->getCurrentHost();
-
\Lamoda\MultiEnv\HostDetector\CliArgsBasedHostDetector - 使用通过Cli脚本运行来识别主机
<?php use \Lamoda\MultiEnv\HostDetector\CliArgsBasedHostDetector; use \Lamoda\MultiEnv\HostDetector\Factory\GetOptAdapterFactory; use \Lamoda\MultiEnv\HostDetector\Exception\HostDetectorException; /* * Search passed needle in CLI args. Use found value to identify current host * Throw HostDetectorException when passed empty needle */ $cliArgsBasedHostDetector = new CliArgsBasedHostDetector('needle', GetOptAdapterFactory::build()); $hostId = $cliArgsBasedHostDetector->getCurrentHost();
-
\Lamoda\MultiEnv\HostDetector\FirstSuccessfulHostDetector - 用于聚合多个HostDetector
<?php use \Lamoda\MultiEnv\HostDetector\ServerHeadersBasedHostDetector; use \Lamoda\MultiEnv\HostDetector\CliArgsBasedHostDetector; use \Lamoda\MultiEnv\HostDetector\Factory\GetOptAdapterFactory; use \Lamoda\MultiEnv\HostDetector\FirstSuccessfulHostDetector; // Iterate through passed HostDetector's and return first not empty HostId $firstSuccessfulHostDetector = new FirstSuccessfulHostDetector([ new CliArgsBasedHostDetector('some_host_id', GetOptAdapterFactory::build()), new ServerHeadersBasedHostDetector('HTTP_HOST_ID') ]); $hostId = $firstSuccessfulHostDetector->getCurrentHost();
可用的FormatterInterface实现
-
\Lamoda\MultiEnv\Formatter\PrefixAppendFormatter - 在原始字符串中追加前缀和分隔符。按照顺序组合 原始字符串、分隔符、主机ID 为 *主机ID*, *分隔符*, *原始字符串*。
<?php use \Lamoda\MultiEnv\Formatter\PrefixAppendFormatter; use \Lamoda\MultiEnv\Model\HostId; use \Lamoda\MultiEnv\Formatter\Exception\FormatterException; $formatter = new PrefixAppendFormatter('__'); // Throw FormatterException if passed empty originalName $formatterName = $formatter->formatName('originalEnvName', new HostId('test_host'));
-
\Lamoda\MultiEnv\Formatter\SuffixAppendFormatter - 在原始字符串中追加后缀和分隔符。按照顺序组合 原始字符串、分隔符、主机ID 为 *原始字符串*, *分隔符*, *主机ID*。
<?php use \Lamoda\MultiEnv\Formatter\SuffixAppendFormatter; use \Lamoda\MultiEnv\Model\HostId; use \Lamoda\MultiEnv\Formatter\Exception\FormatterException; $formatter = new SuffixAppendFormatter('___'); // Throw FormatterException if passed empty originalName $formattedName = $formatter->formatName('originalEnvName', new HostId('test_host'));
-
\Lamoda\MultiEnv\Formatter\CharReplaceFormatter - 类似PHP中的 str_replace。当访问环境变量时,可以将非法字符 '-' 替换为 '_',可能很有用。
<?php use \Lamoda\MultiEnv\Formatter\CharReplaceFormatter; use \Lamoda\MultiEnv\Model\HostId; use \Lamoda\MultiEnv\Formatter\Exception\FormatterException; $formatter = new CharReplaceFormatter('-', '_'); /* * Throw FormatterException if passed empty originalName * return 'original_env_name' */ $formattedName = $formatter->formatName('original-env-name', new HostId('testHost'));
-
\Lamoda\MultiEnv\Formatter\FormatterPipeline - 聚合几个格式化器。遍历它们并将每个应用到原始字符串上。
<?php use \Lamoda\MultiEnv\Formatter\FormatterPipeline; use \Lamoda\MultiEnv\Formatter\SuffixAppendFormatter; use \Lamoda\MultiEnv\Formatter\CharReplaceFormatter; use \Lamoda\MultiEnv\Model\HostId; $formatter = new FormatterPipeline([ new SuffixAppendFormatter('-'), new CharReplaceFormatter('-', '_') ]); // return 'originalEnvName_test_host_id' $formattedName = $formatter->formatName('originalEnvName', new HostId('test-host-id'));