{"id":18561080,"url":"https://github.com/lamoda/multi-env","last_synced_at":"2025-04-10T02:31:20.499Z","repository":{"id":57010939,"uuid":"173910892","full_name":"lamoda/multi-env","owner":"lamoda","description":"Library that provides classes to work with envs in multitenant environment","archived":false,"fork":false,"pushed_at":"2022-10-14T13:08:35.000Z","size":58,"stargazers_count":19,"open_issues_count":0,"forks_count":1,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-03-24T15:42:03.435Z","etag":null,"topics":["environment","environment-variables","multitenant"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lamoda.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-03-05T08:57:14.000Z","updated_at":"2024-07-22T10:44:15.000Z","dependencies_parsed_at":"2022-08-21T13:40:46.520Z","dependency_job_id":null,"html_url":"https://github.com/lamoda/multi-env","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lamoda%2Fmulti-env","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lamoda%2Fmulti-env/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lamoda%2Fmulti-env/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lamoda%2Fmulti-env/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lamoda","download_url":"https://codeload.github.com/lamoda/multi-env/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248144199,"owners_count":21054883,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["environment","environment-variables","multitenant"],"created_at":"2024-11-06T22:05:41.452Z","updated_at":"2025-04-10T02:31:19.969Z","avatar_url":"https://github.com/lamoda.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Lamoda multi-env\n\n[![Build Status](https://travis-ci.org/lamoda/multi-env.svg?branch=master)](https://travis-ci.org/lamoda/multi-env)\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/lamoda/multi-env/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/lamoda/multi-env/?branch=master)\n[![Code Coverage](https://scrutinizer-ci.com/g/lamoda/multi-env/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/lamoda/multi-env/?branch=master)\n[![Build Status](https://scrutinizer-ci.com/g/lamoda/multi-env/badges/build.png?b=master)](https://scrutinizer-ci.com/g/lamoda/multi-env/build-status/master)\n\nLibrary that provides classes to work with envs in multitenant environment\n\nLibrary based on params passed to it on initialization stage will decide which env variable should be used \nfor current request. \n\n## Installation\n\n1. Install library with composer:\n```bash\ncomposer require lamoda/multi-env\n```\n\n## Usage\n\n### Library usage examples to work in not multitenant environment (could be useful in development mode)\n\n```php\n\u003c?php\n\nuse \\Lamoda\\MultiEnv\\Strategy\\RawEnvResolvingStrategy;\nuse \\Lamoda\\MultiEnv\\Decorator\\EnvProviderDecorator;\n\n// RawEnvResolvingStrategy - just wrap native PHP get_env function call\n$strategy = new RawEnvResolvingStrategy();\nEnvProviderDecorator::init($strategy);\n\n// Will be search original TEST_ENV env variable\nEnvProviderDecorator::getEnv('TEST_ENV');\n```\n\n### Library usage examples to work in multitenant environment\n\n```php\n\u003c?php\n\nuse \\Lamoda\\MultiEnv\\Strategy\\HostBasedEnvResolvingStrategy;\nuse \\Lamoda\\MultiEnv\\Strategy\\FileBasedEnvResolvingStrategy;\nuse \\Lamoda\\MultiEnv\\Decorator\\EnvProviderDecorator;\n\n/*\n * Pass as first param one of available HostDetectorInterface implementations\n * Pass as second param one of available EnvNameFormatterInterface implementations\n */\n$strategy = new HostBasedEnvResolvingStrategy($hostDetector, $envFormatter);\nEnvProviderDecorator::init($strategy);\n\n/*\n * Will search env with some specific prefix/suffix resolved by HostDetectorInterface\n * For example host_id__TEST_ENV\n */\nEnvProviderDecorator::getEnv('TEST_ENV');\n\n/*\n * Pass as first param one of available HostDetectorInterface implementations which detect HostId for current request\n * Pass as second param one of available EnvFileReaderInterface (for now available only DotEnvV2FileReaderAdapter) which load specific env file\n * Pass as third param another EnvResolvingStrategy which find specific env variable from loaded envs\n */\n$strategy = new FileBasedEnvResolvingStrategy($hostDetector, $envFileReader, $envResolvingStrategy);\nEnvProviderDecorator::init($strategy);\nEnvProviderDecorator::getEnv('TEST_ENV');\n```\n\n### Library set up by build in factory\n\n1. Library set up for work with env in file stored in different directories\n```php\n\u003c?php\n\nuse \\Lamoda\\MultiEnv\\Builder\\FileBasedEnvResolvingStrategyBuilder;\nuse \\Lamoda\\MultiEnv\\Decorator\\EnvProviderDecorator;\n\n/*\n * Result strategy resolve hostId from server headers or cli args\n * Then load all envs from .env file stored by path /var/envs/*hostId*\n * Read TEST_ENV env variable    \n */\n$strategy = FileBasedEnvResolvingStrategyBuilder::buildStrategy('HTTP_X_HOST_ID', 'host_id', '.env', '/var/envs');\nEnvProviderDecorator::init($strategy);\n\nEnvProviderDecorator::getEnv('TEST_ENV');\n```\n2. Library set up for work with env with prefixes\n```php\n\u003c?php\n\nuse \\Lamoda\\MultiEnv\\Builder\\HostBasedEnvResolvingStrategyBuilder;\nuse \\Lamoda\\MultiEnv\\Decorator\\EnvProviderDecorator;\n\n/*\n * Result strategy resolve hostId from server headers or cli args\n * Add prefix to original env name. Result be like *hostId*___TEST_ENV\n * Replace all '-' char to '_' case '-' illegal in env variable name\n * Read *host_id*___TEST_ENV env variable\n */\n$strategy = HostBasedEnvResolvingStrategyBuilder::buildStrategy('HTTP_X_HOST_ID', 'host_id', '___');\nEnvProviderDecorator::init($strategy);\n\nEnvProviderDecorator::getEnv('TEST_ENV');\n```\n\n### Library set up with multiple strategy\n```php\n\u003c?php\n\nuse \\Lamoda\\MultiEnv\\Strategy\\FirstSuccessfulEnvResolvingStrategy;\nuse \\Lamoda\\MultiEnv\\Strategy\\RawEnvResolvingStrategy;\nuse \\Lamoda\\MultiEnv\\Strategy\\HostBasedEnvResolvingStrategy;\nuse \\Lamoda\\MultiEnv\\HostDetector\\FirstSuccessfulHostDetector;\nuse \\Lamoda\\MultiEnv\\HostDetector\\CliArgsBasedHostDetector;\nuse \\Lamoda\\MultiEnv\\HostDetector\\ServerHeadersBasedHostDetector;\nuse \\Lamoda\\MultiEnv\\Formatter\\PrefixAppendFormatter;\nuse \\Lamoda\\MultiEnv\\HostDetector\\Factory\\GetOptAdapterFactory;\nuse \\Lamoda\\MultiEnv\\Decorator\\EnvProviderDecorator;\n\n$rawEnvResolvingStrategy = new RawEnvResolvingStrategy();\n$hostBasedEnvResolvingStrategy = new HostBasedEnvResolvingStrategy(\n    new FirstSuccessfulHostDetector([\n        new ServerHeadersBasedHostDetector('HTTP_X_TEST_HEADER'),\n        new CliArgsBasedHostDetector('host_id', GetOptAdapterFactory::build())    \n    ]),\n    new PrefixAppendFormatter('___')\n);\n\n$firstSuccessfulStrategy = new FirstSuccessfulEnvResolvingStrategy([\n    $rawEnvResolvingStrategy,\n    $hostBasedEnvResolvingStrategy\n]);\nEnvProviderDecorator::init($firstSuccessfulStrategy);\n\n/*\n * Try find original env 'TEST_ENV' first. \n * If original env not found than try to find env with some specific prefix/suffix resolved by HostDetectorInterface.\n * For example host_id__TEST_ENV\n */\nEnvProviderDecorator::getEnv('TEST_ENV');\n```\n\n## Available HostDetectorInterface implementations\n\n1.  __\\Lamoda\\MultiEnv\\HostDetector\\ServerHeadersBasedHostDetector__ - use to identificate host via HTTP request\n    ```php\n    \u003c?php\n\n    use \\Lamoda\\MultiEnv\\HostDetector\\ServerHeadersBasedHostDetector;\n    use \\Lamoda\\MultiEnv\\HostDetector\\Exception\\HostDetectorException;\n    \n    /*\n     * Search passed needle in $_SERVER header. Use found value to identify current host\n     * Throw HostDetectorException when passed empty needle\n     */\n    $headerBasedHostDetector = new ServerHeadersBasedHostDetector('HTTP_X_SOME_HEADER');\n    $hostId = $headerBasedHostDetector-\u003egetCurrentHost();\n    ``` \n2. __\\Lamoda\\MultiEnv\\HostDetector\\CliArgsBasedHostDetector__ - use to identificate host via Cli script run \n    ```php\n    \u003c?php\n \n    use \\Lamoda\\MultiEnv\\HostDetector\\CliArgsBasedHostDetector;\n    use \\Lamoda\\MultiEnv\\HostDetector\\Factory\\GetOptAdapterFactory;\n    use \\Lamoda\\MultiEnv\\HostDetector\\Exception\\HostDetectorException;\n    \n    /*\n     * Search passed needle in CLI args. Use found value to identify current host\n     * Throw HostDetectorException when passed empty needle\n     */\n    $cliArgsBasedHostDetector = new CliArgsBasedHostDetector('needle', GetOptAdapterFactory::build());\n    $hostId = $cliArgsBasedHostDetector-\u003egetCurrentHost();\n    ```\n\n3. __\\Lamoda\\MultiEnv\\HostDetector\\FirstSuccessfulHostDetector__ - use to aggregate multiple HostDetector's \n    ```php\n    \u003c?php\n \n    use \\Lamoda\\MultiEnv\\HostDetector\\ServerHeadersBasedHostDetector;\n    use \\Lamoda\\MultiEnv\\HostDetector\\CliArgsBasedHostDetector;\n    use \\Lamoda\\MultiEnv\\HostDetector\\Factory\\GetOptAdapterFactory;\n    use \\Lamoda\\MultiEnv\\HostDetector\\FirstSuccessfulHostDetector;\n    \n    // Iterate through passed HostDetector's and return first not empty HostId\n    $firstSuccessfulHostDetector = new FirstSuccessfulHostDetector([\n        new CliArgsBasedHostDetector('some_host_id', GetOptAdapterFactory::build()),\n        new ServerHeadersBasedHostDetector('HTTP_HOST_ID')\n    ]);\n    $hostId = $firstSuccessfulHostDetector-\u003egetCurrentHost();\n    ```\n    \n## Available FormatterInterface implementations\n1. __\\Lamoda\\MultiEnv\\Formatter\\PrefixAppendFormatter__ - append prefix and delimiter to original string. \nCombine __original string__, __delimiter__,__host id__ in order \n\\*__host id__\\*, \\*__delimiter__\\*, \\*__original string__\\*\n    ```php\n    \u003c?php \n \n    use \\Lamoda\\MultiEnv\\Formatter\\PrefixAppendFormatter;\n    use \\Lamoda\\MultiEnv\\Model\\HostId;\n    use \\Lamoda\\MultiEnv\\Formatter\\Exception\\FormatterException;\n \n    $formatter = new PrefixAppendFormatter('__');\n    // Throw FormatterException if passed empty originalName\n    $formatterName = $formatter-\u003eformatName('originalEnvName', new HostId('test_host'));\n    ```\n2. __\\Lamoda\\MultiEnv\\Formatter\\SuffixAppendFormatter__ - append suffix and delimiter to original string.\nCombine __original string__, __delimiter__,__host id__ in order\n\\*__original string__\\*, \\*__delimiter__\\*, \\*__host id__\\*\n    ```php\n    \u003c?php\n    \n    use \\Lamoda\\MultiEnv\\Formatter\\SuffixAppendFormatter;\n    use \\Lamoda\\MultiEnv\\Model\\HostId;\n    use \\Lamoda\\MultiEnv\\Formatter\\Exception\\FormatterException;\n \n    $formatter = new SuffixAppendFormatter('___');\n    // Throw FormatterException if passed empty originalName\n    $formattedName = $formatter-\u003eformatName('originalEnvName', new HostId('test_host'));\n    ```\n3. __\\Lamoda\\MultiEnv\\Formatter\\CharReplaceFormatter__ - act like __str_replace__ in PHP. Could be useful to replace illegal\nchar __'-'__ to __'\\_\\'__ when you access to env variable\n    ```php\n    \u003c?php\n    \n    use \\Lamoda\\MultiEnv\\Formatter\\CharReplaceFormatter;\n    use \\Lamoda\\MultiEnv\\Model\\HostId;\n    use \\Lamoda\\MultiEnv\\Formatter\\Exception\\FormatterException;\n \n    $formatter = new CharReplaceFormatter('-', '_');\n    /*\n     * Throw FormatterException if passed empty originalName\n     * return 'original_env_name'     \n     */\n    $formattedName = $formatter-\u003eformatName('original-env-name', new HostId('testHost'));\n    ```\n\n4. __\\Lamoda\\MultiEnv\\Formatter\\FormatterPipeline__ - aggregate few formatters. Iterate through them and apply each to original stirng\n    ```php\n    \u003c?php \n    \n    use \\Lamoda\\MultiEnv\\Formatter\\FormatterPipeline;\n    use \\Lamoda\\MultiEnv\\Formatter\\SuffixAppendFormatter;\n    use \\Lamoda\\MultiEnv\\Formatter\\CharReplaceFormatter;\n    use \\Lamoda\\MultiEnv\\Model\\HostId;\n    \n    $formatter = new FormatterPipeline([\n       new SuffixAppendFormatter('-'),\n       new CharReplaceFormatter('-', '_')\n    ]);\n \n    // return 'originalEnvName_test_host_id'\n    $formattedName = $formatter-\u003eformatName('originalEnvName', new HostId('test-host-id'));\n    ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flamoda%2Fmulti-env","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flamoda%2Fmulti-env","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flamoda%2Fmulti-env/lists"}