maatwebsite/yamlenv

读取 `env.yml` 并将验证后的变量列表作为环境变量提供

1.0.0 2018-09-19 14:26 UTC

This package is auto-updated.

Last update: 2024-08-28 23:34:53 UTC


README

读取 env.yml 并将验证后的变量列表作为环境变量提供。

本包基于 vlucas/phpdotenv 构建。

Build Status

为什么选择 Yaml 而不是 .env?

使用 env.yml 文件或类似文件的优点已经得到长期验证。vlucas/phpdotenv 和类似包的流行证明了这一点。在项目中使用此类包没有任何理由,尤其是如果您需要管理的变量数量相对较小。

对于更大规模、企业级的应用程序,环境设置的量可能很快就会变得难以管理。如果是一个多租户系统,那就更甚。如果您支持应用程序的不同版本,每个版本都有自己的环境设置列表,那么自动化此过程很快就会成为必要。

这些就是为什么我们决定转向 Yaml 的主要原因。它相对于 env.yml 文件提供了一些简单的好处

  • 它支持嵌套,允许对某些设置进行分组(如数据库连接凭证)。
  • 它既易于人类阅读,也易于多种自动化部署工具(例如 Ansible)读取。
  • 至少有与 Yaml 一起工作的可信赖包一样多(可能更多),其中最重要的一个是 Symfony。

在我们最初的用例中,是嵌套和 Ansible 兼容性的结合使我们决定构建这个包。

使用 Composer 进行安装

composer require maatwebsite/yamlenv ~1.0

使用方法

以下文档大部分与 Vlucas/Dotenv 相同。当然,文件名和类名已经更改。我们尽量让该包的使用方法与 Dotenv 尽可能相似,以便于使用。因此,请向 Vlucas 致谢,因为他提供了一个如此出色的基础。

当然,还有一些 Yamlenv 独有的东西,也已经添加进来了。

通常将 env.yml 文件排除在版本控制之外,因为它可能包含敏感的 API 密钥和密码。可以创建一个单独的 env.yml.dist 文件,其中定义了所有必要的环境变量(不包括敏感的变量),这些敏感变量由用户为自己的开发环境提供,或者在其他地方与项目合作者沟通。然后,项目合作者独立地将 env.yml.dist 文件复制到本地的 env.yml,并确保所有设置对于其本地环境是正确的,在必要时填写秘密密钥或提供自己的值。在这种情况下,应将 env.yml 文件添加到项目的 .gitignore 文件中,以确保合作者永远不会将其提交。这种使用方法确保敏感密码或 API 密钥永远不会出现在版本控制历史中,从而降低了安全漏洞的风险,并且生产值永远不会与所有项目合作者共享。

将您的应用程序配置添加到项目根目录中的 env.yml 文件中。请确保将 env.yml 文件添加到您的 .gitignore,以便它不会被代码检查入。

S3_BUCKET: "yamlenv"
SECRET_KEY: "secret_key"

现在创建一个名为 env.yml.dist 的文件并将其提交到项目中。这个文件应包含您需要设置的 ENV 变量,但值应该是空的或填充了模拟数据。目的是让人们知道需要哪些变量,但不提供敏感的生产值。

S3_BUCKET: "devbucket"
SECRET_KEY: "abc123"

然后您可以用以下方式在应用程序中加载 env.yml

$yamlenv = new Yamlenv\Yamlenv(__DIR__);
$yamlenv->load();

可选地,您可以传递一个文件名作为第二个参数,如果您想使用除 env.yml 之外的内容。

$yamlenv = new Yamlenv\Yamlenv(__DIR__, 'myconfig');
$yamlenv->load();

现在所有定义的变量都可以通过 getenv 方法访问,并且可以在 $_ENV$_SERVER 超全局变量中找到。

$s3_bucket = getenv('S3_BUCKET');
$s3_bucket = $_ENV['S3_BUCKET'];
$s3_bucket = $_SERVER['S3_BUCKET'];

您也可以通过您的框架的 Request 类(如果您正在使用框架)访问它们。

$s3_bucket = $request->env('S3_BUCKET');
$s3_bucket = $request->getEnv('S3_BUCKET');
$s3_bucket = $request->server->get('S3_BUCKET');
$s3_bucket = env('S3_BUCKET');

大写键

使用 Yamlenv,您可以将布尔值 true 作为第三个构造函数参数。这将确保所有键都将转换为大写。

s3_bucket: "will_be_uppercase"
$yamlenv = new Yamlenv\Yamlenv(__DIR__, 'emv.yml', true);
$yamlenv->load();
$s3_bucket = getenv('S3_BUCKET'); // return will_be_uppercase
$s3_bucket = getenv('s3_bucket'); // returns null

嵌套变量

类似于 Dotenv,您可以在另一个环境变量内部嵌套环境变量。然而,由于我们使用 Yaml 格式,嵌套是原生支持的。

DB:
  USER: username
  PASS: password
  HOST: localhost

这些变量将在添加到环境变量之前被扁平化到一个级别。不同的键将连接成一个单个键,键之间用下划线分隔。所以上面的例子会给出以下结果

DB_USER: username
DB_PASS: password
DB_HOST: localhost

这也适用于多层嵌套

FOO:
  BAR: 
    LOREM:
        IPSUM: multilevelfun
FOO_BAR_LOREM_IPSUM: multilevelfun

不可变性

默认情况下,Yamlenv 不会覆盖环境中已经设置的环境变量。

如果您想让 Yamlenv 覆盖现有的环境变量,请使用 overload 而不是 load

$yamlenv = new Yamlenv\Yamlenv(__DIR__);
$yamlenv->overload();

要求设置变量

使用 Yamlenv,您需要特定的 ENV 变量被定义,如果它们未定义则抛出异常。这特别有用,可以让人们知道应用程序无法在没有明确所需的变量的情况下运行。

您可以使用一个字符串

$yamlenv->required('DATABASE_DSN');

或一个字符串数组

$yamlenv->required(['DB_HOST', 'DB_NAME', 'DB_USER', 'DB_PASS']);

如果任何 ENV 变量缺失,Yamlenv 将抛出类似于以下的 RuntimeException

One or more environment variables failed assertions: DATABASE_DSN is missing

空变量

除了要求变量被设置之外,您可能还需要确保变量不为空。

$yamlenv->required('DATABASE_DSN')->notEmpty();

如果环境变量为空,您将得到一个异常。

One or more environment variables failed assertions: DATABASE_DSN is empty

整型变量

您可能还需要确保变量是整数值。您可以这样做

$yamlenv->required('FOO')->isInteger();

如果环境变量不是整型,您将得到一个异常。

One or more environment variables failed assertions: FOO is not an integer

允许的值

您也可以定义一组环境变量应该具有的值。这在代码只支持少量选项或驱动程序的情况下特别有用。

$yamlenv->required('SESSION_STORE')->allowedValues(['Filesystem', 'Memcached']);

如果环境变量不在这个允许的值列表中,您将得到一个类似的异常。

One or more environment variables failed assertions: SESSION_STORE is not an
allowed value

注释

您可以使用 # 字符注释您的 env.yml 文件。例如,这遵循正常的 Yaml 语法规则。

# this is a comment
VAR: "value" # comment
VAR: value # comment

当嵌套变量时,始终使用基于键->值的子项非常重要。虽然以下内容是有效的 Yaml,但它不会产生可用的变量。

FOO:
  - one
  - two

正确的方式是

FOO:
  BAR: one
  BAZ: two

使用说明

当新开发者克隆您的代码库时,他们将有一个额外的 一次性步骤,即手动将 env.yml.dist 文件复制到 env.yml 并填写他们自己的值(或从项目同事那里获取任何敏感值)。

Yamlenv 是为开发环境制作的,通常不应在生产环境中使用。在生产环境中,应该设置实际的环境变量,以便在每个请求中无需加载 env.yml 文件而产生开销。这可以通过使用像 Vagrant、chef 或 Puppet 这样的自动化部署工具来实现,或者可以通过像 Pagodabox 和 Heroku 这样的云主机手动设置。