{"id":17623454,"url":"https://github.com/m1/env","last_synced_at":"2025-04-07T09:18:36.391Z","repository":{"id":2938427,"uuid":"47935133","full_name":"m1/Env","owner":"m1","description":"Env is a lightweight library bringing .env file parser compatibility to PHP. In short - it enables you to read .env files with PHP.","archived":false,"fork":false,"pushed_at":"2022-05-11T10:26:34.000Z","size":68,"stargazers_count":61,"open_issues_count":5,"forks_count":9,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-07T09:18:32.153Z","etag":null,"topics":["env","environment","environment-variables","php","php-library","php-package"],"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/m1.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-13T20:29:25.000Z","updated_at":"2024-07-20T06:40:35.000Z","dependencies_parsed_at":"2022-08-08T22:30:12.818Z","dependency_job_id":null,"html_url":"https://github.com/m1/Env","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m1%2FEnv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m1%2FEnv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m1%2FEnv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m1%2FEnv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/m1","download_url":"https://codeload.github.com/m1/Env/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247622983,"owners_count":20968575,"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":["env","environment","environment-variables","php","php-library","php-package"],"created_at":"2024-10-22T21:09:33.671Z","updated_at":"2025-04-07T09:18:36.366Z","avatar_url":"https://github.com/m1.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Env\n\n[![Author](http://img.shields.io/badge/author-@milescroxford-blue.svg?style=flat-square)](https://twitter.com/milescroxford)\n[![Latest Version on Packagist][ico-version]][link-packagist]\n[![Software License][ico-license]](LICENSE.md)\n[![Build Status][ico-travis]][link-travis]\n[![Coverage Status][ico-scrutinizer]][link-scrutinizer]\n[![Quality Score][ico-code-quality]][link-code-quality]\n[![Downloads][ico-downloads]][link-downloads]\n[![StyleCI](https://styleci.io/repos/47935133/shield)](https://styleci.io/repos/47935133)\n\n[![Sensio badge][ico-sensio]][link-sensio]\n\nEnv is a lightweight library bringing .env file parser compatibility to PHP. In short - it enables you to read .env files with PHP.\n\n* [Why?](#why)\n* [Requirements](#requirements)\n* [Install](#install)\n* [Usage](#usage)\n    * [Basic](#basic)\n    * [Context variables](#context)\n    * [Syntax](#syntax)\n        * [Assignment](#assignment)\n        * [Strings](#strings)\n        * [Numbers](#numbers)\n        * [Booleans](#booleans)\n        * [Null](#null)\n        * [Variables](#variables)\n            * [Default Value/Assignment](#parameter-expansion)\n        * [Comments](#comments)\n    * [.env example](#env-example)\n* [Notes](#notes)\n    * [Source](#source)\n* [Other library comparisons](#other-library-comparisons)\n* [Todo](#todo)\n* [Change log](#change-log)\n* [Testing](#testing)\n* [Contributing](#Contributing)\n* [Security](#security)\n* [Credits](#credits)\n* [License](#license)\n\n\n## Why?\nEnv aims to bring a unified parser for env together for PHP rather than having a few incomplete or buggy parsers written \ninto other libraries. This library is not meant as a complete package for config loading like other libraries as this \nis out of scope for this library. If you need something like that check out [Vars](http://github.com/m1/Vars) which incorporates\nthis library so you can load Env and other file types if you want, or checkout [PHP Dotenv](https://github.com/josegonzalez/php-dotenv)\nif you only need .env parsing\n\n## Requirements\n\nEnv requires PHP version `5.3+` - supported and tested on `5.3`, `5.4`, `5.5`, `5.6`, `7` and `hhvm`.\n\n## Install\n\nVia Composer\n\n``` bash\n$ composer require m1/env\n```\n\n## Usage\n\n### Basic\n\ntest.env\n```bash\nTEST_1 = VALUE\n```\n\nexample.php\n```php\n\u003c?php\n\n//both examples return the same thing\n\n// example 1 -- standard\nuse M1\\Env\\Parser;\n\n$env = new Parser(file_get_contents('test.env'));\n$arr = $env-\u003egetContent();\n\n// example 2 -- statically\n$arr = Parser::parse(file_get_contents('test.env'));\n\nvar_dump($arr);\n// [\n//      \"TEST_1\" =\u003e \"VALUE\"\n// ]\n```\n### Context variables\n\ntest_context.env\n```bash\nTEST_1 = $EXTERNAL\nTEST_2 = VALUE\n```\n\nexample_context.php\n```php\n\u003c?php\n\n//both examples return the same thing\n\n// example 1 -- standard\nuse M1\\Env\\Parser;\n\n$env = new Parser(file_get_contents('test_context.env'), array('EXTERNAL' =\u003e 'external'));\n$arr = $env-\u003egetContent();\n\n// example 2 -- statically\n$arr = Parser::parse(file_get_contents('test_context.env'), array('EXTERNAL' =\u003e 'external'));\n\nvar_dump($arr);\n// [\n//      \"TEST_1\" =\u003e \"external\"\n//      \"TEST_2\" =\u003e \"VALUE\"\n// ]\n```\n\n### Syntax\n\nThe Syntax is slightly more relaxed than bash, but still remains quite bash like\n\n#### Assignment\nTo assign values the syntax is `key = value`, unlike bash the assignment is pretty relaxed, any of the below are valid:\n```bash\nTEST1 = value\nTEST2= VALUE\nTEST3 =VALUE\nTEST4=VALUE\n TEST5 = VALUE\nTEST6  =   VALUE\n```\n\nHowever keys can not start with a number, e.g.:\n\n```bash\n1notvalid = nope\n```\n\nWill throw a `ParseException`\n\nYou can also add `export` to the start of variables to `source` the file in bash ([see here](#source) for more info):\n\n```bash\nexport TEST1=value\n```\n\n#### Strings\n\nStrings can either be in quotes (single or double) or without:\n\n```bash\nTEST1 = value\nTEST2 = \"value\"\nTEST3 = 'value'\n```\n\nTo escape new lines or quotes is the standard backslash:\n\n```bash\nTEST1 = \"value \\n value\"\nTEST2 = \"value \\\"value\\\" value\"\nTEST3 = 'value \\' value \\' value'\n```\n\nIf you feature two quoted strings as a value then only the first quoted string will be assigned to the key:\n\n```bash\nTEST1 = \"value value\" \"this sentence in quotes will not be counted\"\n```\n\n#### Numbers\n\nNumbers are fairly standard:\n```bash\nTEST1 = 1\nTEST2 = 2\n```\n\nDecimal numbers will be automatically cast to floats:\n```bash\nTEST1 = 1.1 # `float` type\nTEST2 = 2   # `int` type\n```\n\nIf you quote numbers they will be counted as strings, or if you have two numbers on one line:\n```bash\nTEST1 = 33 33 # `string` type\nTEST2 = \"22\"  # `string` type\n```\n\n#### Booleans\n\nBooleans can be `true`, `false`, `yes` and `no`:\n```bash\nTEST1 = true\nTEST2 = false\nTEST3 = yes\nTEST4 = no\n```\n\nBooleans are case-insensitive:\n```bash\nTEST1 = True\nTEST2 = False\nTEST3 = YES\nTEST4 = NO\n```\n\nBooleans in quotes will be treated as strings:\n```bash\nTEST1 = \"true\" # `string` type\nTEST2 = \"YES\"  # `string` type\nTEST3 = 'NO'   # `string` type\n```\n\n#### Null\n\nBoth of the below are counted as null values:\n```bash\nTEST1 =\nTEST2 = null\n```\n\nWhereas an empty string is counted as a string:\n```bash\nTEST1 = \"\" # `string` type\nTEST2 = '' # `string` type\n```\n\n#### Variables\n\nVariables are based of the bash syntax:\n```bash\nTEST1 = 'hello'\nTEST2 = ${TEST27} # 'hello'\n```\n\nThe types of variable get passed to the calling variable if there is only one variable. If there are more than one variable,\nthe calling variable is automatically cast to a string:\n```bash\nTEST1 = 1 # `int` type\nTEST2 = 2 # `int` type\nTEST3 = ${TEST1} ${TEST2} # `string` type\nTEST4 = true     # `bool` type\nTEST5 = ${TEST4} # `bool` type\n```\n\nAlso if the variable is in quotes then the variable will be automatically cast as a string:\n```bash\nTEST1 = 1 # `int` type\nTEST2 = \"${TEST1}\" # `string` type\n```\n\nBut you can use variables without quotes and they'll be cast as strings:\n```bash\nTEST1 = foo\nTEST2 = bar\nTEST3 = ${TEST1}/${TEST2} # `string` type\n```\n\nVariables are useful to use in strings like so:\n```bash\nTEST1 = \"foo\"\nTEST2 = 'bar'\nTEST3 = \"hello ${TEST1} and ${TEST2}\"\n```\n\nNull values are passed and casted as empty strings if in quotes:\n```bash\nTEST1 = null\nTEST2 = ${TEST1} # `null` type\nTEST3 = \"${TEST1}\" # `string` type\n```\n\nSingle Quotes with variables will be counted as strings:\n```bash\nTEST1 = '${hello} # `string` type, will output: '${hello}'\n```\n\n\n##### Parameter Expansion\n\nYou can do parameter expansion, so far you can only do [default values](http://wiki.bash-hackers.org/syntax/pe#use_a_default_value) \nand [assign default values](http://wiki.bash-hackers.org/syntax/pe#assign_a_default_value) like in the bash syntax:\n\n```bash\nTEST1 = foo\nTEST2 = ${TEST3:=bar}\nTEST4 = ${TEST5=bar}\nTEST6 = ${TEST7:-bar}\nTEST8 = ${TEST9-bar}\n```\n\nThe default value parameter expansion syntax is `:-`, the explanation on the [bash-hackers wiki](http://wiki.bash-hackers.org/syntax/pe#use_a_default_value) for this is:\n\u003e SYNTAX:\n\u003e\n\u003e`${PARAMETER:-WORD}`\n\u003e\n\u003e`${PARAMETER-WORD}`\n\u003e\n\u003eIf the parameter PARAMETER is unset (never was defined) or null (empty), this one expands to WORD, otherwise it \n\u003eexpands to the value of PARAMETER, as if it just was ${PARAMETER}. If you omit the : (colon), like shown in the second \n\u003eform, the default value is only used when the parameter was unset, not when it was empty.\n\nFor example:\n```bash\nTEST1 = foo\nTEST2 = ${TEST1:-bar} # TEST1 is set so the value of TEST2 = foo\n\nTEST3 = ${TEST4:-bar} # TEST4 is not set so the value of TEST3 = bar\n\nTEST5 = null\nTEST6 = ${TEST5-bar} # TEST5 is set but empty so the value of TEST6 = null\nTEST7 = ${TEST6:-bar} # TEST5 is set and empty so the value of TEST7 = bar\n\n```\n\nThe assign default value parameter expansion is `:=`, the explanation on the [bash-hackers wiki](http://wiki.bash-hackers.org/syntax/pe#assign_a_default_value) for this is:\n\u003e SYNTAX:\n\u003e\n\u003e`${PARAMETER:=WORD}`\n\u003e\n\u003e`${PARAMETER=WORD}`\n\u003e\n\u003eThis one works like the using default values, but the default text you give is not only expanded, but also assigned \n\u003eto the parameter, if it was unset or null. Equivalent to using a default value, when you omit the : (colon), as \n\u003eshown in the second form, the default value will only be assigned when the parameter was unset.\n\nFor example:\n```bash\nTEST1 = foo\nTEST2 = ${TEST1:=bar} # TEST1 is set so the value of TEST2 = foo\n\nTEST3 = ${TEST4:=bar} # TEST4 is not set so the value of TEST3 = bar and TEST4 = bar\n\nTEST5 = null\nTEST6 = ${TEST5=bar} # TEST5 is set but emtpy so the value of TEST6 = null \nTEST7 = ${TEST6=bar} # TEST5 is set and empty so the value of TEST7 = bar and TEST5 = bar\n```\n#### Comments\n\nTo comment, just use the `#` syntax, you can also comment inline like so:\n```bash\n# This is a comment\nTEST1 = bar # and so is this\n```\n\nIf you put a `#` without a space in a unquoted string, it will be parsed as a string:\n\n```bash\nTEST1 = hello#notacomment\n```\n\n### .env example\n\n```bash\n# Comments are done like this\n\n# Standard key=value\nTEST1 = value\nTEST2 = value\nTEST3 = value # You can also comment inline like this\n\n# Strings\nTEST4 = \"value\"\n\n## The value of the below variable will be TK4 = \"value value\"\nTEST5 = \"value value\" \"this sentence in quotes will not be counted\"\n\n## Escape newline\nTEST6 = \"value \\n value\"\n\n## Escape double quotes\nTEST7 = \"value \\\"value\\\" value\"\n\n## You can also exchange any of the above for single quotes, eg:\nTEST8 = 'value'\nTEST9 = 'value \\' value \\' value'\n\n# Numbers\nTEST10 = 1\nTEST11 = 1.1\nTEST12 = 33 33 # Will output as a `string` -- not a number as two numbers are given\nTEST13 = \"33\" # 33 -- `string` type\n\n# Bools -- All of the below are valid booleans\nTEST14 = true\nTEST15 = false\nTEST16 = yes\nTEST17 = no\n\n## Booleans are case-insensitive\nTEST18 = True\nTEST19 = False\nTEST20 = YES\nTEST21 = NO\n\nTEST22 = \"true\" # \"true\" -- `string` type\nTEST23 = \"YES\" # \"YES\" -- `string` type\nTEST24 = 'NO' # \"NO\" -- `string` type\n\n# Null values\nTEST25 =\nTEST26 = null\n\n# Variables\nTEST27 = 'hello'\nTEST28 = ${TEST27} # 'hello'\n\nTEST29 = 1\nTEST30 = 2\nTEST31 = ${TEST29}   # 1 -- `int` type\nTEST32 = \"${TEST29}\" # 1 -- `string` type\nTEST33 = ${TEST29} ${TEST30} # 1 2 -- `string` type\n\nTEST34 = foo\nTEST35 = bar\nTEST36 = ${TEST34}/${TEST35} # foo/bar -- `string` type\n\nTEST37 = \"foo\"\nTEST38 = 'bar'\nTEST39 = \"hello ${TEST37} and ${TEST38}\" # hello foo and bar -- `string` type\n\nTEST40 = true\nTEST41 = false\nTEST42 = ${TEST40} # true -- `bool` type\nTEST43 = ${TEST40} ${TEST41} # true false -- `string` type\n\nTEST44 = null\nTEST45 = ${TEST44} # null -- `null` type\nTEST46 = \"${TEST44}\" # '' -- `string` type\nTEST46_5 = '${TEST44}' # '' -- `string` type\n\nTEST47=foo\nTEST48=${TEST47:=bar}\nTEST49=${TEST50:=foo}\nTEST51=${TEST52:-foo}\nTEST53=null\nTEST54=${TEST53=foo}\nTEST55=null\nTEST56=${TEST55-foo}\nTEST57=${TEST58:=\"\"}\nTEST59=${TEST60:=null} # TEST59 = null TEST60 = null -- both `null` types\nTEST61=${TEST62:=true} # TEST61 = true TEST62 = true -- both `bool` types\n\n# Comments\nTEST63 = hello # comment\nTEST64 = \"hello # comment\"\nTEST65 = \"hello\" #comment\nTEST66 = #comment\nTEST67 = \"#comment\"\nTEST68 = thisisnota#comment\n```\n\nThe result from this library and the expected result of the above is:\n\n```php\narray(\n    \"TEST1\" =\u003e \"value\",\n    \"TEST2\" =\u003e \"value\",\n    \"TEST3\" =\u003e \"value\",\n    \"TEST4\" =\u003e \"value\",\n    \"TEST5\" =\u003e \"value value\",\n    \"TEST6\" =\u003e \"value \\n value\",\n    \"TEST7\" =\u003e 'value \"value\" value',\n    \"TEST8\" =\u003e \"value\",\n    \"TEST9\" =\u003e \"value ' value ' value\",\n    \"TEST10\" =\u003e 1,\n    \"TEST11\" =\u003e 1.1,\n    \"TEST12\" =\u003e \"33 33\",\n    \"TEST13\" =\u003e \"33\",\n    \"TEST14\" =\u003e true,\n    \"TEST15\" =\u003e false,\n    \"TEST16\" =\u003e true,\n    \"TEST17\" =\u003e false,\n    \"TEST18\" =\u003e true,\n    \"TEST19\" =\u003e false,\n    \"TEST20\" =\u003e true,\n    \"TEST21\" =\u003e false,\n    \"TEST22\" =\u003e \"true\",\n    \"TEST23\" =\u003e \"YES\",\n    \"TEST24\" =\u003e 'NO',\n    \"TEST25\" =\u003e null,\n    \"TEST26\" =\u003e null,\n    \"TEST27\" =\u003e \"hello\",\n    \"TEST28\" =\u003e \"hello\",\n    \"TEST29\" =\u003e 1,\n    \"TEST30\" =\u003e 2,\n    \"TEST31\" =\u003e 1,\n    \"TEST32\" =\u003e \"1\",\n    \"TEST33\" =\u003e \"1 2\",\n    \"TEST34\" =\u003e \"foo\",\n    \"TEST35\" =\u003e \"bar\",\n    \"TEST36\" =\u003e \"foo/bar\",\n    \"TEST37\" =\u003e \"foo\",\n    \"TEST38\" =\u003e 'bar',\n    \"TEST39\" =\u003e \"hello foo and bar\",\n    \"TEST40\" =\u003e true,\n    \"TEST41\" =\u003e false,\n    \"TEST42\" =\u003e true,\n    \"TEST43\" =\u003e \"true false\",\n    \"TEST44\" =\u003e null,\n    \"TEST45\" =\u003e null,\n    \"TEST46\" =\u003e \"\",\n    \"TEST46_5\" =\u003e \"${TEST44}\",\n    'TEST47' =\u003e 'foo',\n    'TEST48' =\u003e 'foo',\n    'TEST50' =\u003e 'foo',\n    'TEST49' =\u003e 'foo',\n    'TEST51' =\u003e 'foo',\n    'TEST53' =\u003e null,\n    'TEST54' =\u003e null,\n    'TEST55' =\u003e null,\n    'TEST56' =\u003e null,\n    'TEST58' =\u003e '',\n    'TEST57' =\u003e '',\n    'TEST60' =\u003e null,\n    'TEST59' =\u003e null,\n    'TEST62' =\u003e true,\n    'TEST61' =\u003e true,\n    'TEST63' =\u003e 'hello # comment',\n    'TEST64' =\u003e 'hello',\n    'TEST66' =\u003e null,\n    'TEST67' =\u003e '#comment',\n    'TEST68' =\u003e 'thisisnota#comment',\n);\n```\n## Notes\n\n### Source\n\nIf you need the .env variables in other applications, you can `source` the env, but make sure it's valid bash syntax, as this parser allows a more relaxed form of bash syntax.\n\n```bash\nsource .env\n```\n\nThis library will always be able to parse bash syntax, but for now the opposite (env syntax -\u003e bash syntax) may not be true, however this is being worked on to bring a strict parser version for `3.0`\n\n## Other library comparisons\n\nThe difference between this library and other similar libraries:\n\n#### `zrcing/phpenv`: \n- Converts all value types to string\n- Does not support `null` values\n- Does not support `int`, `float` or `bool` types\n- Does not support variables\n\n#### `Dotenv\\Dotenv`:\n- Does not support unquoted values like `33 33`, this should be cast to string. See `TEST12`\n- Does not support concatenation of variables unquoted like `${VAR} ${VAR2}`, this should be cast to string. See `TEST33`\n- Both of the above crash `Dotenv` without a helpful exception\n- Converts all value types to string\n- Does not support `null` values\n- Does not support `int`, `float` or `bool` types\n- Does not support variables\n- Does not support [parameter expansions](#parameter-expansion)\n- Does not support inline comments where there is no value. See `TEST66`\n\n\n## Todo\n- [Other bash parameter expansions](http://wiki.bash-hackers.org/syntax/pe#display_error_if_null_or_unset)\n\n## Change log\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.\n\n## Testing\n\n``` bash\n$ composer test\n```\n\n## Contributing\n\nPlease see [CONTRIBUTING](CONTRIBUTING.md) and [CONDUCT](CONDUCT.md) for details.\n\n## Security\n\nIf you discover any security related issues, please email hello@milescroxford.com instead of using the issue tracker.\n\n## Credits\n\n- [m1][link-author]\n- [All Contributors][link-contributors]\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n\n[ico-version]: https://img.shields.io/packagist/v/m1/Env.svg?style=flat-square\n[ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square\n[ico-travis]: https://img.shields.io/travis/m1/Env/master.svg?style=flat-square\n[ico-scrutinizer]: https://img.shields.io/scrutinizer/coverage/g/m1/Env.svg?style=flat-square\n[ico-hhvm]: https://img.shields.io/hhvm/m1/Env.svg?style=flat-square\n[ico-code-quality]: https://img.shields.io/scrutinizer/g/m1/Env.svg?style=flat-square\n[ico-downloads]: https://img.shields.io/packagist/dt/m1/Env.svg?style=flat-square\n[ico-sensio]: https://insight.sensiolabs.com/projects/1fb8cbab-f611-45b5-8a45-0113e433eab7/big.png\n\n[link-packagist]: https://packagist.org/packages/m1/Env\n[link-travis]: https://travis-ci.org/m1/Env\n[link-scrutinizer]: https://scrutinizer-ci.com/g/m1/Env/code-structure\n[link-code-quality]: https://scrutinizer-ci.com/g/m1/Env\n[link-downloads]: https://packagist.org/packages/m1/Env\n[link-author]: https://github.com/m1\n[link-contributors]: ../../contributors\n[link-sensio]: https://insight.sensiolabs.com/projects/1fb8cbab-f611-45b5-8a45-0113e433eab7\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm1%2Fenv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fm1%2Fenv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm1%2Fenv/lists"}