PHP dotenv

repository·master·Indexed 12 days ago

https://github.com/vlucas/phpdotenv

A tool for loading environment variables from a .env file into PHP's super-globals ($_ENV, $_SERVER) and getenv(). It supports immutable and mutable loading, variable nesting, and validation of environment variables using the Dotenv\Validator class to ensure required configuration is present and valid.

Tokens
5.7K
Snippets
26
Records
30
Agent score
95%

What's inside PHP dotenv

  1. Immutability and Repository Customization

    master

    Immutability determines whether Dotenv is allowed to overwrite existing environment variables.

    • Immutable (Default): Use createImmutable(). It will not overwrite variables that are already set in the environment.
    • Mutable: Use createMutable() if you want Dotenv to overwrite existing environment variables.

    For advanced configurations, you can use the RepositoryBuilder to define specific adapters (like EnvConstAdapter or PutenvAdapter) and set immutability or an allow-list of variables.

    // Example: Custom repository with specific adapters and immutability
    $repository = Dotenv\Repository\RepositoryBuilder::createWithNoAdapters()
        ->addAdapter(Dotenv\Repository\Adapter\EnvConstAdapter::class)
        ->addWriter(Dotenv\Repository\Adapter\PutenvAdapter::class)
        ->immutable()
        ->make();
    
    $dotenv = Dotenv\Dotenv::create($repository, __DIR__);
    $dotenv->load();
    
    // Example: Using an allow-list
    $repository = Dotenv\Repository\RepositoryBuilder::createWithDefaultAdapters()
        ->allowList(['FOO', 'BAR'])
        ->make();
    
    $dotenv = Dotenv\Dotenv::create($repository, __DIR__);
    $dotenv->load();
  2. Nesting environment variables

    master

    You can reuse existing environment variables within your .env file by wrapping them in ${...} syntax. This is useful for reducing repetition in configuration.

    BASE_DIR="/var/webroot/project-root"
    CACHE_DIR="${BASE_DIR}/cache"
    TMP_DIR="${BASE_DIR}/tmp"
  3. How to use getenv() and putenv() with PHP dotenv

    master

    By default, PHP dotenv does not use getenv() and putenv() because they are not thread-safe. If your application requires these functions, use Dotenv::createUnsafeImmutable(). This adds the PutenvAdapter automatically, making variables available via getenv() as well as $_ENV and $_SERVER.

    $dotenv = Dotenv\Dotenv::createUnsafeImmutable(__DIR__);
    $dotenv->load();
    
    $s3_bucket = getenv('S3_BUCKET');
    $s3_bucket = $_ENV['S3_BUCKET'];
  4. Upgrade from V4.0 to V4.1

    master
    Version 4.1 is a minor release with no breaking changes, but it introduces a deprecation: passing an array of file paths as the third parameter to the Dotenv\Dotenv constructor is deprecated and will be removed in V5. Use an instance of Dotenv\Store\StoreInterface instead.
  5. Upgrade from V4 to V5

    master

    Upgrading to V5 requires PHP 7.1+. Key changes include:

    1. getenv and putenv usage: Dotenv\Dotenv::createImmutable and Dotenv\Dotenv::createMutable no longer call getenv and putenv. If you need these functions, you must use Dotenv\Dotenv::createUnsafeImmutable or Dotenv\Dotenv::createUnsafeMutable.
    2. Constructor changes: The Dotenv\Dotenv constructor now requires exactly 4 parameters (store, parser, loader, repository). It is recommended to continue using the static create* methods instead.
    3. Repository Builder refactor: The RepositoryBuilder no longer includes default adapters. You must explicitly add readers and writers. Use createWithNoAdapters() to start from scratch or createWithDefaultAdapters() to start with defaults.
    4. Adapter instantiation: You cannot construct adapters directly. Use their static create() method (which returns an Optional) or pass the class name to the builder to allow the library to handle system compatibility checks automatically.
    // New way to build a repository in V5
    $repository = Dotenv\Repository\RepositoryBuilder::createWithNoAdapters()
        ->addAdapter(Dotenv\Repository\Adapter\EnvConstAdapter::class)
        ->addWriter(Dotenv\Repository\Adapter\PutenvAdapter::class)
        ->make();
  6. Migrate from V2 to V3

    master

    When upgrading from version 2 to version 3, several breaking changes in initialization and parsing must be addressed:

    1. Initialization: Replace new Dotenv(...) with the static factory method Dotenv::create(...). The new constructor requires a Loader instance for customization.
    2. Return Values: Loader::load() and its callers now return an associative array of the loaded variables (key => value) instead of an array of raw lines.
    3. Value Trimming: The loader no longer automatically trims whitespace from parsed values.
    4. Parsing Changes:
      • Comments: For unquoted strings, a # character is now treated as the start of a comment.
      • Multiline Support: Multiline quoted values are now supported.
      • Escaping: The parser is stricter regarding invalid escape sequences in quoted strings.
    5. PHP Version: The minimum supported PHP version increased from 5.3.9 to 5.4.0.
  7. Upgrade from V3 to V4

    master

    Upgrading to V4 involves significant changes to how immutability is handled and how the library is initialized:

    1. Immutability: Immutability is now decided at construction. Replace Dotenv::create with Dotenv::createImmutable for immutable loading, or Dotenv::createMutable for mutable loading. The overload() method has been removed; use createMutable and ->load() instead.
    2. Variable Interpolation: Interpolation now runs right-to-left, allowing nested interpolations. You can also escape dollar signs ($) in unquoted or double-quoted strings to prevent interpolation.
    3. Single Quoted Strings: Single quoted strings now behave like bash; they are treated literally and do not support character escaping.
    4. Getting Variable Names: getEnvironmentVariableNames() is removed. Use array_keys($dotenv->load()) instead.
    5. PHP Version: The minimum supported version is now PHP 5.5.9.
    // V4 initialization pattern
    use Dotenv\Dotenv;
    use Dotenv\Repository\Adapter\EnvConstAdapter;
    use Dotenv\Repository\Adapter\ServerConstAdapter;
    use Dotenv\Repository\RepositoryBuilder;
    
    $adapters = [
    	new EnvConstAdapter(),
    	new ServerConstAdapter(),
    ];
    
    $repository = RepositoryBuilder::create()
        ->withReaders($adapters)
        ->withWriters($adapters)
        ->immutable()
        ->make();
    
    Dotenv::create($repository, $path, null)->load();
  8. Basic usage of PHP dotenv

    master

    To load environment variables from a .env file into $_ENV and $_SERVER, use Dotenv::createImmutable(). By default, it looks for a .env file in the directory provided.

    Note: Always add your .env file to .gitignore to prevent sensitive credentials from being committed to version control. It is best practice to create a .env.example file with dummy values to guide other collaborators.

    $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
    $dotenv->load();
    
    // Access variables via super-globals
    $s3_bucket = $_ENV['S3_BUCKET'];
    $s3_bucket = $_SERVER['S3_BUCKET'];
  9. Troubleshooting: $_ENV and $_SERVER are empty

    master
    If $_ENV or $_SERVER are not being populated in certain server environments (like shared hosting), check your php.ini configuration. Specifically, ensure the variables_order directive includes E (for Environment) and S (for Server).
  10. Configure custom Repository with Adapters in V5

    master

    In V5, when using the RepositoryBuilder, you can pass class names to addAdapter or addWriter. This is safer because the library will only instantiate the adapter if it is compatible with the current environment (e.g., checking if Apache functions are available).

    // Simulating V4 behavior with ApacheAdapter in V5
    $builder = Dotenv\Repository\RepositoryBuilder::createWithDefaultAdapters();
    
    Dotenv\Repository\Adapter\ApacheAdapter::create()->map(function ($adapter) {
        return new Dotenv\Repository\Adapter\ReplacingWriter($adapter, $adapter);
    })->map([$builder, 'addWriter'])->getOrElse($builder);
    
    $repository = $builder->make();