m1/env
Composer 安装命令:
composer require m1/env
包简介
Env is a lightweight library bringing .env file parser compatibility to PHP. In short - it enables you to read .env files with PHP.
README 文档
README
Env is a lightweight library bringing .env file parser compatibility to PHP. In short - it enables you to read .env files with PHP.
- Why?
- Requirements
- Install
- Usage
- Notes
- Other library comparisons
- Todo
- Change log
- Testing
- Contributing
- Security
- Credits
- License
Why?
Env aims to bring a unified parser for env together for PHP rather than having a few incomplete or buggy parsers written into other libraries. This library is not meant as a complete package for config loading like other libraries as this is out of scope for this library. If you need something like that check out Vars which incorporates this library so you can load Env and other file types if you want, or checkout PHP Dotenv if you only need .env parsing
Requirements
Env requires PHP version 5.3+ - supported and tested on 5.3, 5.4, 5.5, 5.6, 7 and hhvm.
Install
Via Composer
$ composer require m1/env
Usage
Basic
test.env
TEST_1 = VALUE
example.php
<?php //both examples return the same thing // example 1 -- standard use M1\Env\Parser; $env = new Parser(file_get_contents('test.env')); $arr = $env->getContent(); // example 2 -- statically $arr = Parser::parse(file_get_contents('test.env')); var_dump($arr); // [ // "TEST_1" => "VALUE" // ]
Context variables
test_context.env
TEST_1 = $EXTERNAL
TEST_2 = VALUE
example_context.php
<?php //both examples return the same thing // example 1 -- standard use M1\Env\Parser; $env = new Parser(file_get_contents('test_context.env'), array('EXTERNAL' => 'external')); $arr = $env->getContent(); // example 2 -- statically $arr = Parser::parse(file_get_contents('test_context.env'), array('EXTERNAL' => 'external')); var_dump($arr); // [ // "TEST_1" => "external" // "TEST_2" => "VALUE" // ]
Syntax
The Syntax is slightly more relaxed than bash, but still remains quite bash like
Assignment
To assign values the syntax is key = value, unlike bash the assignment is pretty relaxed, any of the below are valid:
TEST1 = value TEST2= VALUE TEST3 =VALUE TEST4=VALUE TEST5 = VALUE TEST6 = VALUE
However keys can not start with a number, e.g.:
1notvalid = nope
Will throw a ParseException
You can also add export to the start of variables to source the file in bash (see here for more info):
export TEST1=value
Strings
Strings can either be in quotes (single or double) or without:
TEST1 = value TEST2 = "value" TEST3 = 'value'
To escape new lines or quotes is the standard backslash:
TEST1 = "value \n value" TEST2 = "value \"value\" value" TEST3 = 'value \' value \' value'
If you feature two quoted strings as a value then only the first quoted string will be assigned to the key:
TEST1 = "value value" "this sentence in quotes will not be counted"
Numbers
Numbers are fairly standard:
TEST1 = 1 TEST2 = 2
Decimal numbers will be automatically cast to floats:
TEST1 = 1.1 # `float` type TEST2 = 2 # `int` type
If you quote numbers they will be counted as strings, or if you have two numbers on one line:
TEST1 = 33 33 # `string` type TEST2 = "22" # `string` type
Booleans
Booleans can be true, false, yes and no:
TEST1 = true TEST2 = false TEST3 = yes TEST4 = no
Booleans are case-insensitive:
TEST1 = True TEST2 = False TEST3 = YES TEST4 = NO
Booleans in quotes will be treated as strings:
TEST1 = "true" # `string` type TEST2 = "YES" # `string` type TEST3 = 'NO' # `string` type
Null
Both of the below are counted as null values:
TEST1 = TEST2 = null
Whereas an empty string is counted as a string:
TEST1 = "" # `string` type TEST2 = '' # `string` type
Variables
Variables are based of the bash syntax:
TEST1 = 'hello' TEST2 = ${TEST27} # 'hello'
The types of variable get passed to the calling variable if there is only one variable. If there are more than one variable, the calling variable is automatically cast to a string:
TEST1 = 1 # `int` type TEST2 = 2 # `int` type TEST3 = ${TEST1} ${TEST2} # `string` type TEST4 = true # `bool` type TEST5 = ${TEST4} # `bool` type
Also if the variable is in quotes then the variable will be automatically cast as a string:
TEST1 = 1 # `int` type TEST2 = "${TEST1}" # `string` type
But you can use variables without quotes and they'll be cast as strings:
TEST1 = foo TEST2 = bar TEST3 = ${TEST1}/${TEST2} # `string` type
Variables are useful to use in strings like so:
TEST1 = "foo" TEST2 = 'bar' TEST3 = "hello ${TEST1} and ${TEST2}"
Null values are passed and casted as empty strings if in quotes:
TEST1 = null TEST2 = ${TEST1} # `null` type TEST3 = "${TEST1}" # `string` type
Single Quotes with variables will be counted as strings:
TEST1 = '${hello} # `string` type, will output: '${hello}'
Parameter Expansion
You can do parameter expansion, so far you can only do default values and assign default values like in the bash syntax:
TEST1 = foo TEST2 = ${TEST3:=bar} TEST4 = ${TEST5=bar} TEST6 = ${TEST7:-bar} TEST8 = ${TEST9-bar}
The default value parameter expansion syntax is :-, the explanation on the bash-hackers wiki for this is:
SYNTAX:
${PARAMETER:-WORD}
${PARAMETER-WORD}If the parameter PARAMETER is unset (never was defined) or null (empty), this one expands to WORD, otherwise it expands to the value of PARAMETER, as if it just was ${PARAMETER}. If you omit the : (colon), like shown in the second form, the default value is only used when the parameter was unset, not when it was empty.
For example:
TEST1 = foo TEST2 = ${TEST1:-bar} # TEST1 is set so the value of TEST2 = foo TEST3 = ${TEST4:-bar} # TEST4 is not set so the value of TEST3 = bar TEST5 = null TEST6 = ${TEST5-bar} # TEST5 is set but empty so the value of TEST6 = null TEST7 = ${TEST6:-bar} # TEST5 is set and empty so the value of TEST7 = bar
The assign default value parameter expansion is :=, the explanation on the bash-hackers wiki for this is:
SYNTAX:
${PARAMETER:=WORD}
${PARAMETER=WORD}This one works like the using default values, but the default text you give is not only expanded, but also assigned to the parameter, if it was unset or null. Equivalent to using a default value, when you omit the : (colon), as shown in the second form, the default value will only be assigned when the parameter was unset.
For example:
TEST1 = foo TEST2 = ${TEST1:=bar} # TEST1 is set so the value of TEST2 = foo TEST3 = ${TEST4:=bar} # TEST4 is not set so the value of TEST3 = bar and TEST4 = bar TEST5 = null TEST6 = ${TEST5=bar} # TEST5 is set but emtpy so the value of TEST6 = null TEST7 = ${TEST6=bar} # TEST5 is set and empty so the value of TEST7 = bar and TEST5 = bar
Comments
To comment, just use the # syntax, you can also comment inline like so:
# This is a comment TEST1 = bar # and so is this
If you put a # without a space in a unquoted string, it will be parsed as a string:
TEST1 = hello#notacomment
.env example
# Comments are done like this # Standard key=value TEST1 = value TEST2 = value TEST3 = value # You can also comment inline like this # Strings TEST4 = "value" ## The value of the below variable will be TK4 = "value value" TEST5 = "value value" "this sentence in quotes will not be counted" ## Escape newline TEST6 = "value \n value" ## Escape double quotes TEST7 = "value \"value\" value" ## You can also exchange any of the above for single quotes, eg: TEST8 = 'value' TEST9 = 'value \' value \' value' # Numbers TEST10 = 1 TEST11 = 1.1 TEST12 = 33 33 # Will output as a `string` -- not a number as two numbers are given TEST13 = "33" # 33 -- `string` type # Bools -- All of the below are valid booleans TEST14 = true TEST15 = false TEST16 = yes TEST17 = no ## Booleans are case-insensitive TEST18 = True TEST19 = False TEST20 = YES TEST21 = NO TEST22 = "true" # "true" -- `string` type TEST23 = "YES" # "YES" -- `string` type TEST24 = 'NO' # "NO" -- `string` type # Null values TEST25 = TEST26 = null # Variables TEST27 = 'hello' TEST28 = ${TEST27} # 'hello' TEST29 = 1 TEST30 = 2 TEST31 = ${TEST29} # 1 -- `int` type TEST32 = "${TEST29}" # 1 -- `string` type TEST33 = ${TEST29} ${TEST30} # 1 2 -- `string` type TEST34 = foo TEST35 = bar TEST36 = ${TEST34}/${TEST35} # foo/bar -- `string` type TEST37 = "foo" TEST38 = 'bar' TEST39 = "hello ${TEST37} and ${TEST38}" # hello foo and bar -- `string` type TEST40 = true TEST41 = false TEST42 = ${TEST40} # true -- `bool` type TEST43 = ${TEST40} ${TEST41} # true false -- `string` type TEST44 = null TEST45 = ${TEST44} # null -- `null` type TEST46 = "${TEST44}" # '' -- `string` type TEST46_5 = '${TEST44}' # '' -- `string` type TEST47=foo TEST48=${TEST47:=bar} TEST49=${TEST50:=foo} TEST51=${TEST52:-foo} TEST53=null TEST54=${TEST53=foo} TEST55=null TEST56=${TEST55-foo} TEST57=${TEST58:=""} TEST59=${TEST60:=null} # TEST59 = null TEST60 = null -- both `null` types TEST61=${TEST62:=true} # TEST61 = true TEST62 = true -- both `bool` types # Comments TEST63 = hello # comment TEST64 = "hello # comment" TEST65 = "hello" #comment TEST66 = #comment TEST67 = "#comment" TEST68 = thisisnota#comment
The result from this library and the expected result of the above is:
array( "TEST1" => "value", "TEST2" => "value", "TEST3" => "value", "TEST4" => "value", "TEST5" => "value value", "TEST6" => "value \n value", "TEST7" => 'value "value" value', "TEST8" => "value", "TEST9" => "value ' value ' value", "TEST10" => 1, "TEST11" => 1.1, "TEST12" => "33 33", "TEST13" => "33", "TEST14" => true, "TEST15" => false, "TEST16" => true, "TEST17" => false, "TEST18" => true, "TEST19" => false, "TEST20" => true, "TEST21" => false, "TEST22" => "true", "TEST23" => "YES", "TEST24" => 'NO', "TEST25" => null, "TEST26" => null, "TEST27" => "hello", "TEST28" => "hello", "TEST29" => 1, "TEST30" => 2, "TEST31" => 1, "TEST32" => "1", "TEST33" => "1 2", "TEST34" => "foo", "TEST35" => "bar", "TEST36" => "foo/bar", "TEST37" => "foo", "TEST38" => 'bar', "TEST39" => "hello foo and bar", "TEST40" => true, "TEST41" => false, "TEST42" => true, "TEST43" => "true false", "TEST44" => null, "TEST45" => null, "TEST46" => "", "TEST46_5" => "${TEST44}", 'TEST47' => 'foo', 'TEST48' => 'foo', 'TEST50' => 'foo', 'TEST49' => 'foo', 'TEST51' => 'foo', 'TEST53' => null, 'TEST54' => null, 'TEST55' => null, 'TEST56' => null, 'TEST58' => '', 'TEST57' => '', 'TEST60' => null, 'TEST59' => null, 'TEST62' => true, 'TEST61' => true, 'TEST63' => 'hello # comment', 'TEST64' => 'hello', 'TEST66' => null, 'TEST67' => '#comment', 'TEST68' => 'thisisnota#comment', );
Notes
Source
If 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.
source .env
This library will always be able to parse bash syntax, but for now the opposite (env syntax -> bash syntax) may not be true, however this is being worked on to bring a strict parser version for 3.0
Other library comparisons
The difference between this library and other similar libraries:
zrcing/phpenv:
- Converts all value types to string
- Does not support
nullvalues - Does not support
int,floatorbooltypes - Does not support variables
Dotenv\Dotenv:
- Does not support unquoted values like
33 33, this should be cast to string. SeeTEST12 - Does not support concatenation of variables unquoted like
${VAR} ${VAR2}, this should be cast to string. SeeTEST33 - Both of the above crash
Dotenvwithout a helpful exception - Converts all value types to string
- Does not support
nullvalues - Does not support
int,floatorbooltypes - Does not support variables
- Does not support parameter expansions
- Does not support inline comments where there is no value. See
TEST66
Todo
Change log
Please see CHANGELOG for more information what has changed recently.
Testing
$ composer test
Contributing
Please see CONTRIBUTING and CONDUCT for details.
Security
If you discover any security related issues, please email hello@milescroxford.com instead of using the issue tracker.
Credits
License
The MIT License (MIT). Please see License File for more information.
m1/env 适用场景与选型建议
m1/env 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 12.67M 次下载、GitHub Stars 达 61, 最近一次更新时间为 2015 年 12 月 13 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「parser」 「config」 「loader」 「support」 「env」 「dotenv」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 m1/env 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 m1/env 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 m1/env 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Symfony2 bundle that provides features to load assets
Easy to use SDK with grabber for multiple platforms at once like YouTube, Dailymotion, Facebook and more.
A Zend Framework module to quickly and easily set PHP settings.
An MT940 bank statement parser for PHP
An environment variable convenience library extension for vlucas/phpdotenv
PhpStratum SQLite: A stored procedure loader and wrapper generator for SQLite
统计信息
- 总下载量: 12.67M
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 64
- 点击次数: 26
- 依赖项目数: 22
- 推荐数: 2
其他信息
- 授权协议: MIT
- 更新时间: 2015-12-13