m1/env

Env 是一个轻量级的库,它为 PHP 带来了 .env 文件解析器的兼容性。简而言之,它使您能够使用 PHP 读取 .env 文件。

2.2.0 2020-02-19 09:02 UTC

This package is auto-updated.

Last update: 2024-09-21 20:38:31 UTC


README

Author Latest Version on Packagist Software License Build Status Coverage Status Quality Score Downloads StyleCI

Sensio badge

Env 是一个轻量级的库,它为 PHP 带来了 .env 文件解析器的兼容性。简而言之,它使您能够使用 PHP 读取 .env 文件。

为什么?

Env 旨在为 PHP 带来一个统一的 env 解析器,而不是让其他库中有几个不完整或存在错误的解析器。这个库不打算作为一个像其他库那样的完整配置加载包,因为这超出了这个库的范围。如果您需要这样的东西,请查看 Vars,它包含了这个库,因此如果您想的话,您可以加载 Env 和其他文件类型,或者如果您只需要 .env 解析,请查看 PHP Dotenv

需求

Env 需要 PHP 版本 5.3+ - 支持并已在 5.35.45.55.67hhvm 上测试过。

安装

通过 Composer

$ composer require m1/env

用法

基本

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"
// ]

上下文变量

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"
// ]

语法

语法比 bash 略为宽松,但仍然保留了很多 bash 的特点。

赋值

赋值语法是 key = value,与 bash 不同,赋值相当宽松,以下任何一种都是有效的:

TEST1 = value
TEST2= VALUE
TEST3 =VALUE
TEST4=VALUE
 TEST5 = VALUE
TEST6  =   VALUE

但是键不能以数字开头,例如:

1notvalid = nope

将抛出 ParseException

您还可以在变量的开头添加 export 以在 bash 中 source 文件(有关更多信息,请参阅此处)。

export TEST1=value

字符串

字符串可以是带引号的(单引号或双引号)或不带引号的。

TEST1 = value
TEST2 = "value"
TEST3 = 'value'

转义换行符或引号的标准转义字符是反斜杠。

TEST1 = "value \n value"
TEST2 = "value \"value\" value"
TEST3 = 'value \' value \' value'

如果您将两个引号字符串作为值,则只有第一个引号字符串将被分配给键。

TEST1 = "value value" "this sentence in quotes will not be counted"

数字

数字相当标准。

TEST1 = 1
TEST2 = 2

十进制数字将被自动转换为浮点数。

TEST1 = 1.1 # `float` type
TEST2 = 2   # `int` type

如果您引用数字,则它们将被视为字符串,或者如果您在一行中有两个数字

TEST1 = 33 33 # `string` type
TEST2 = "22"  # `string` type

布尔值

布尔值可以是 truefalseyesno

TEST1 = true
TEST2 = false
TEST3 = yes
TEST4 = no

布尔值不区分大小写。

TEST1 = True
TEST2 = False
TEST3 = YES
TEST4 = NO

引号中的布尔值将被视为字符串。

TEST1 = "true" # `string` type
TEST2 = "YES"  # `string` type
TEST3 = 'NO'   # `string` type

空值

以下两种都被视为空值

TEST1 =
TEST2 = null

而空字符串被视为字符串。

TEST1 = "" # `string` type
TEST2 = '' # `string` type

变量

变量基于 bash 语法。

TEST1 = 'hello'
TEST2 = ${TEST27} # 'hello'

如果只有一个变量,则变量类型将传递给调用变量。如果有多个变量,则调用变量将自动转换为字符串。

TEST1 = 1 # `int` type
TEST2 = 2 # `int` type
TEST3 = ${TEST1} ${TEST2} # `string` type
TEST4 = true     # `bool` type
TEST5 = ${TEST4} # `bool` type

如果变量在引号中,则变量将被自动转换为字符串。

TEST1 = 1 # `int` type
TEST2 = "${TEST1}" # `string` type

但是您也可以使用不带引号的变量,它们将被转换为字符串。

TEST1 = foo
TEST2 = bar
TEST3 = ${TEST1}/${TEST2} # `string` type

变量在字符串中的使用如下所示

TEST1 = "foo"
TEST2 = 'bar'
TEST3 = "hello ${TEST1} and ${TEST2}"

空值会被传递并转换为空字符串(如果用引号引用)。

TEST1 = null
TEST2 = ${TEST1} # `null` type
TEST3 = "${TEST1}" # `string` type

带有变量的单引号将被视为字符串。

TEST1 = '${hello} # `string` type, will output: '${hello}'
参数展开

您可以进行参数扩展,目前您只能执行类似于bash语法中的默认值分配默认值

TEST1 = foo
TEST2 = ${TEST3:=bar}
TEST4 = ${TEST5=bar}
TEST6 = ${TEST7:-bar}
TEST8 = ${TEST9-bar}

默认值参数扩展语法是:-,在bash-hackers wiki上的解释如下:

SYNTAX

${PARAMETER:-WORD}

${PARAMETER-WORD}

如果参数PARAMETER未设置(从未定义)或为空,则扩展为WORD,否则扩展为PARAMETER的值,就像它是${PARAMETER}。如果您省略了:(冒号),如第二种形式所示,默认值仅在参数未设置时使用,而不在它为空时使用。

例如

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

分配默认值参数扩展是:=,在bash-hackers wiki上的解释如下:

SYNTAX

${PARAMETER:=WORD}

${PARAMETER=WORD}

这与使用默认值类似,但您提供的默认文本不仅会扩展,还会分配给参数,如果它未设置或为空。如果省略:(冒号),如第二种形式所示,默认值仅在参数未设置时分配。

例如

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

注释

要注释,只需使用#语法,您还可以这样使用行内注释

# This is a comment
TEST1 = bar # and so is this

如果您在一个未引用的字符串中放置一个没有空格的#,它将被解析为字符串

TEST1 = hello#notacomment

.env 示例

# 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

此库的结果与上述预期的结果是

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',
);

注意

源代码

如果您需要在其他应用程序中使用.env变量,可以source env,但请确保它是有效的bash语法,因为此解析器允许更宽松的bash语法形式。

source .env

此库始终可以解析bash语法,但到目前为止,反向操作(env语法 -> bash语法)可能不成立,但是目前正在努力为3.0版本带来严格的解析器版本。

与其他库的比较

此库与其他类似库之间的区别

zrcing/phpenv:

  • 将所有值类型转换为字符串
  • 不支持null
  • 不支持intfloatbool类型
  • 不支持变量

Dotenv\Dotenv:

  • 不支持未引用的值,如33 33,这应该被转换为字符串。参见TEST12
  • 不支持未引用的变量连接,如${VAR} ${VAR2},这应该被转换为字符串。参见TEST33
  • 上述两种情况都会使Dotenv崩溃,而不会提供有用的异常
  • 将所有值类型转换为字符串
  • 不支持null
  • 不支持intfloatbool类型
  • 不支持变量
  • 不支持参数扩展
  • 不支持在无值的空格处使用行内注释。参见TEST66

待办事项

变更日志

请参阅CHANGELOG了解最近的变化。

测试

$ composer test

贡献

请参阅CONTRIBUTINGCONDUCT以获取详细信息。

安全

如果您发现任何与安全相关的问题,请通过电子邮件[email protected]联系,而不是使用问题跟踪器。

鸣谢

许可

MIT许可(MIT)。请参阅许可文件了解更多信息。