302dev/dotenv

PHPdotenv文件解析

dev-master 2023-02-17 20:32 UTC

This package is auto-updated.

Last update: 2024-09-22 20:01:16 UTC


README

Build Status Coverage Status Total Downloads Latest Stable Version

PHP Dotenv

PHP的.env文件解析和加载库。

需求

  • PHP 5.5+

安装

[使用 Composer]

运行 composer require josegonzalez/dotenv:

或者将插件添加到项目的 composer.json 文件中,如下所示

  {
    "require": {
      "josegonzalez/dotenv": "3.3.0"
    }
  }

用法

创建新的加载器

<?php
$Loader = new josegonzalez\Dotenv\Loader('path/to/.env');
// Parse the .env file
$Loader->parse();
// Send the parsed .env file to the $_ENV variable
$Loader->toEnv();
?>

大多数方法返回加载器本身,所以以下也是可能的

<?php
$Loader = (new josegonzalez\Dotenv\Loader('path/to/.env'))
              ->parse()
              ->toEnv(); // Throws LogicException if ->parse() is not called first
?>

您可以使用具有以下功能的.env文件

# comments are allowed
FOO=bar # you can also have comments on the end of a line
export BAR=baz # you can optionally begin with an `export` statement

# both single and double quotes are allowed
BAZ='qux'
QUX="quux"

# as are escaped quotes or similar:
QUUX="corge \" grault"
CORGE='garply" waldo'

# unquoted values containing [null, true, false] are turned into
# their PHP equivalents
PHP_NULL=null
PHP_TRUE=true
PHP_FALSE=false

# when quoted, they are simply string values
STRING_NULL="null"
STRING_TRUE="true"
STRING_FALSE="false"

# spaces are allowed as well
# in a slightly more relaxed form from bash
 GRAULT =fred
GARPLY = plugh
SPACES=" quote values with spaces" # will contain preceding space

# When using newlines, you should use quoted values
QUOTED_NEWLINE="newline\\nchar"

# you can even have nested variables using `${VAR}` syntax
# remember to define the nested var *before* using it
WALDO=${xyzzy} # not yet defined, so will result in WALDO = `{}`
THUD=${GARPLY} # will be defined as `plugh`

# note that variables beginning with a character
# other than [a-zA-Z_] shall throw a ParseException
01SKIPPED=skipped

# However, numbers *are* allowed elsewhere in the key
NOT_SKIPPED1=not skipped # will have the value `not`

示例.env文件可在fixtures目录中找到。

定义常量

您还可以从env文件自动定义常量

<?php
$Loader = (new josegonzalez\Dotenv\Loader('path/to/.env'))
              ->parse()
              ->define(); // Throws LogicException if ->parse() is not called first
?>

已定义的常量将导致立即抛出LogicException

添加到$_ENV

<?php
$overwriteENV = true;
$Loader = (new josegonzalez\Dotenv\Loader('path/to/.env'))
              ->parse()
              ->toEnv($overwriteENV); // Throws LogicException if ->parse() is not called first
?>

已定义的$_ENV条目将导致立即抛出LogicException,除非$overwriteENV设置为true(默认为false)。

添加到$_SERVER

<?php
$overwriteSERVER = true;
$Loader = (new josegonzalez\Dotenv\Loader('path/to/.env'))
              ->parse()
              ->toServer($overwriteSERVER); // Throws LogicException if ->parse() is not called first
?>

已定义的$_SERVER条目将导致立即抛出LogicException,除非$overwriteSERVER设置为true(默认为false)。

使apache_getenv()可用

当使用带有mod_php的Apache Web服务器时,应首选使用此方法而不是getenv

<?php
$overwrite = true;
$Loader = (new josegonzalez\Dotenv\Loader('path/to/.env'))
              ->parse()
              ->apacheSetenv($overwriteAPACHE); // Throws LogicException if ->parse() is not called first
                                                // May throw a PHP Error if either apache_setenv() or apache_putenv() are not available
?>

使apache_getenv()可用

已定义的apache_getenv()条目将导致立即抛出LogicException,除非$overwriteAPACHE设置为true(默认为false)。

<?php
$overwrite = true;
$Loader = (new josegonzalez\Dotenv\Loader('path/to/.env'))
              ->parse()
              ->putenv($overwriteENV); // Throws LogicException if ->parse() is not called first
?>

使getenv()可用

设置键前缀

<?php
$environment = (new josegonzalez\Dotenv\Loader('path/to/.env'))
              ->parse()
              ->prefix('FOO')
              ->toServer(); // BAR=baz becomes FOOBAR=baz
?>

作为数组返回

<?php
$environment = (new josegonzalez\Dotenv\Loader('path/to/.env'))
              ->parse()
              ->toArray(); // Throws LogicException if ->parse() is not called first
?>

作为json返回

<?php
$jsonEnvironment = (string)((new josegonzalez\Dotenv\Loader('path/to/.env'))->parse());
?>

需要环境变量

<?php
$Loader = (new josegonzalez\Dotenv\Loader('path/to/.env'))
              ->parse()
              ->expect('FOO', 'BAR', 'BAZ'); // Throws RuntimeException if variables are missing
?>

关闭异常

<?php
$Loader = (new josegonzalez\Dotenv\Loader('path/to/.env'))
              ->raiseExceptions(false)
              ->parse()
              ->expect('FOO', 'BAR', 'BAZ'); // Returns false if variables are missing
?>

跳过现有环境变量

在容器化/Docker设置中,可以跳过现有环境变量(例如)。

<?php
$Loader = (new josegonzalez\Dotenv\Loader('path/to/.env'))
              ->parse()
              ->skipExisting() //Skip any environment variables that are already present
              ->putenv();
?>

过滤环境

您可以通过使用过滤器类来选择性地过滤php-dotenv生成的环境数据。一个过滤器类具有以下__invoke方法

<?php
class LollipopFilter
{
    /**
     * Sets every key's value to the string `lollipop`
     *
     * @param array $environment Array of environment data
     * @param array $config Array of configuration data that includes the callable
     * @return array
     */
    public function __invoke(array $environment, array $config)
    {
        $newEnvironment = [];
        foreach ($environment as $key => $value) {
            $newEnvironment[$key] = 'lollipop';
        }
        return $newEnvironment;
    }
}
?>

您可以使用setFilters()方法附加过滤器,这将覆盖所有当前指定的过滤器。如果指定了无效的过滤器,将抛出LogicException

<?php
$Loader = (new josegonzalez\Dotenv\Loader('path/to/.env'))
              ->setFilters(['LollipopFilter']); // Takes an array of namespaced class names
?>

请注意,您可以可选地为过滤器设置配置。这些配置作为第二个参数传递给__invoke方法。

<?php
$Loader = (new josegonzalez\Dotenv\Loader('path/to/.env'))
              ->setFilters([
                'LollipopFilter' => ['paintshop'],
              ]); // Takes an array of namespaced class names
?>

过滤器也可以是可调用函数,这在一次性情况下很有用。它们由特殊的CallableFilter包装。

<?php
$Loader = (new josegonzalez\Dotenv\Loader('path/to/.env'))
              ->setFilters([function ($data) {
                return $data;
              }]);
?>

如果您需要为可调用过滤器设置特殊配置,您可以在可调用前加上__callable__N前缀,其中N是可调用在数组中的整数索引。可调用本身应包含在callable配置键中,如下所示

<?php
$Loader = (new josegonzalez\Dotenv\Loader('path/to/.env'))
              ->setFilters([
                '__callable__0' => [
                  'callable' => function ($data, $config) {
                    return $data;
                  },
                  'someKey' => 'value',
                ]
              ]);
?>

最后,在调用parse()后,必须调用filter()来调用过滤器。

<?php
$Loader = (new josegonzalez\Dotenv\Loader('path/to/.env'))
              ->setFilters(['LollipopFilter'])
              ->parse()
              ->filter();
?>

可用过滤器

以下过滤器是php-dotenv内建的。

  • josegonzalez\Dotenv\Filter\CallableFilter:包装可调用并在环境上调用它。
  • josegonzalez\Dotenv\Filter\LowercaseKeyFilter:将环境的所有键转换为单层深度的小写。
  • josegonzalez\Dotenv\Filter\NullFilter:返回未经任何更改的环境数据。
  • josegonzalez\Dotenv\Filter\RemapKeysFilter:将$config数组中的特定键重映射到单层深度的值集。
  • josegonzalez\Dotenv\Filter\UnderscoreArrayFilter:将扁平数组展开为嵌套数组。例如,['0_Foo_Bar' => 'Far']变为[['Foo' => ['Bar' => 'Far']]]
  • josegonzalez\Dotenv\Filter\UppercaseFirstKeyFilter:将环境的所有键的第一个字母转换为大写,变为单层深度。
  • josegonzalez\Dotenv\Filter\UrlParseFilter:当存在以_URL结尾的键时,此过滤器使用parse_url向环境添加额外数据。

静态环境定义

您还可以通过静态的load方法调用它,该方法接受一个参数数组。如果指定了方法名,则该方法将使用$options数组中的值调用该方法。

<?php
josegonzalez\Dotenv\Loader::load(array(
  'filepath' => 'path/to/.env',
  'expect' => array('FOO', 'BAR', 'BAZ'),
  'toEnv' => true,
  'toServer' => true,
  'define' => true,
));
?>

验证外部环境

在某些情况下,可能需要验证给定的环境数据数组是否符合您的要求。您可以通过独立的Expect类使用Loader->expect()功能。

<?php
use josegonzalez\Dotenv\Expect;

$expect = new Expect($env);
$expect('FOO'); // Raises a RuntimeException if `env` is missing FOO

// You can turn off exception raising using the second `raise` argument
$expect = new Expect($env, false);
$expect('FOO'); // Returns false if `env` is missing FOO
?>

这是什么?为什么我应该使用它?

在开发和部署应用程序时,您通常会与各种环境进行交互 - 例如生产环境和开发环境。这两个环境都会执行您的代码,但会使用不同的凭证。您还可能希望将应用程序分发给开发者,而不会意外地让他们访问重要的外部服务。

简单的例子包括电子邮件提供程序的认证密钥或数据库连接凭证。您绝对不希望不小心向所有用户发送测试邮件,或者因为在运行单元测试时执行了DROP TABLE语句。

您如何处理这些不同的凭证?php-dotenv通过允许您以通用方式配置环境来解决此问题,使您能够轻松地在环境之间安全切换,以及与多个项目/语言共享这些环境。

还需要更多理由吗?请查看12个因素应用程序配置文档

遵循的规则

当使用php-dotenv时,您应努力遵守以下规则

  • 将您的.env文件添加到gitignore中,并使用.env.default.env.example来设置项目的默认值。这允许您的开发团队在适用于其本地环境的方法中覆盖默认值。

  • 始终为任何凭证设置合理的开发默认值。如果需要,在凭证“无效”时禁用功能。

  • 必要时,在凭证中添加注释,说明它们是什么,如何使用,以及如何获取新的凭证。

  • 由于php-dotenv在定义环境变量时采用更宽松的程序,请确保您的.env文件与您的shell兼容。一种很好的测试方法是运行以下命令

    # source in your .env file
    source .env
    # check the environment
    env
  • 避免在生产环境中运行php-dotenv,而是在运行命令之前在web服务器、进程管理器或在bash中设置环境变量。确保这一点的简单方法是在生产中仅设置特定环境变量作为哨兵变量。

    // APP_NAME isn't set in staging/dev
    if (!env('APP_NAME')) {
        $loader = new josegonzalez\Dotenv\Loader([
            __DIR__ '/.env',
            __DIR__ '/.env.default'
        ]);
        $loader->parse()->toEnv();
    }

一般安全信息

如果您将php-dotenv配置为以上述任何方式输出配置并将它们导出,它们可能会对不希望的用户可用。例如,如果与$Loader->toServer()结合使用filp/whoops项目,并且您在生产中启用了whoops,则可能会将敏感数据输出给您的用户。

因此,php-dotenv 默认不会向环境变量填充数据,并要求开发者做出明确的决策,关于他们希望如何使用加载的环境变量。

许多错误报告工具都提供了白名单或黑名单敏感数据的选项,你应该熟悉这些工具。

许可证

MIT许可证(MIT)

版权所有(c)2013 Jose Diaz-Gonzalez

特此授予任何获得此软件及其相关文档副本(“软件”)的人免费使用权,可以在不受限制的情况下处理软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件的副本,并允许获得软件的人进行此类操作,前提是遵守以下条件

上述版权声明和本许可声明应包含在软件的所有副本或实质性部分中。

本软件按“原样”提供,不提供任何形式的保证,无论是明示的、暗示的还是其他的,包括但不限于适销性、适用于特定目的和非侵权性保证。在任何情况下,作者或版权所有者都不对任何索赔、损害或其他责任负责,无论是基于合同、侵权或其他行为,无论是源于、因之或与此软件或其使用或其他方式有关。