vlucas/phpdotenv
65.4
Adequate · 25 September 2026
3k
lines of production code
PHP
primary language
4
measurements over time
What this system is
This system is a PHP library for loading and validating environment variables from files and server configurations. It provides a modular architecture that parses .env files with support for Unicode, nested variable resolution, and multiple character encodings. The library allows users to define strict validation rules for variables and manages their storage through a flexible adapter layer that supports various backends like $\_SERVER, $\_ENV, and in-memory arrays.
How it got here
2013 — Architecture modernization and standardization
6 changes.
The project underwent a significant architectural refactor to replace monolithic loading logic with a modular system of Store, Parser, Loader, and Validator components. This period also focused on standardizing the development environment through .editorconfig, Docker-based tooling, and a comprehensive dependency overhaul to support modern PHP versions.
2015–2019 — Repository and Store abstraction
7 changes.
This period focused on refactoring the core environment variable management architecture by introducing adapter-based repositories and store abstractions. The work standardized how variables are read, written, and resolved through new interfaces and concrete implementations, replacing direct file-reading approaches with a more modular and testable design. Additionally, custom exception classes and comprehensive test fixtures were added to ensure robust error handling and edge-case coverage.
2020 — Parser rewrite and test coverage
7 changes.
The parser implementation was completely rewritten to improve robustness, performance, and Unicode support, introducing Result types for explicit error handling. Comprehensive unit tests were added for the parser, loader, repository, and store components to ensure correctness across various encoding and edge cases. Internal utility classes were also introduced to standardize string manipulation and regex operations with proper error handling.
Features
Introduction of custom exception classes for environment handling
The library now provides specific exception types within the \Dotenv\\Exception\ namespace to handle distinct error scenarios. Users can now catch \InvalidEncodingException\ for file encoding issues, \InvalidFileException\ for invalid file problems, \InvalidPathException\ for path errors, and \ValidationException\ for validation failures. All these classes implement the new \ExceptionInterface\ and extend standard PHP exceptions (\InvalidArgumentException\ or \RuntimeException\), allowing for more granular error handling in applications.
src/Exception · high confidence
New adapter layer for environment variable management
The repository now includes a new adapter subsystem in src/Repository/Adapter that standardizes how environment variables are read, written, and deleted. This introduces core interfaces (ReaderInterface, WriterInterface, AdapterInterface) and several concrete adapters: ApacheAdapter for Apache-specific functions, ArrayAdapter for in-memory storage, EnvConstAdapter and ServerConstAdapter for reading/writing to the $\_ENV and $\_SERVER superglobals, and PutenvAdapter for the standard putenv/getenv functions. It also adds composite writers (MultiWriter, GuardedWriter, ImmutableWriter, ReplacingWriter) to allow chaining, restricting writes to allow-listed names, preventing overwrites of existing variables, or replacing existing values, as well as a MultiReader for checking multiple sources.
src/Repository/Adapter · high confidence
New internal string and regex utility classes with error handling
The src/Util directory now includes two new internal helper classes, Regex and Str, to standardize string manipulation and regular expression operations. The Regex class wraps PHP's preg\\ functions (match, occurrences, replaceCallback, split) to return Result types that capture PCRE errors via preg\_last\error, preventing silent failures. The Str class provides UTF-8 aware string operations (utf8 conversion, position, substring, length) using mb\\* functions, including specific support for stripping Byte Order Marks (BOM) from UTF-8 encoded content and validating character encodings before conversion.
src/Util · high confidence
New loader and resolver components for environment variable handling
The src/Loader area introduces three new classes: LoaderInterface, Loader, and Resolver. The Loader class implements the interface to process parser entries, handling both variable setting and clearing in the repository. The Resolver class provides static methods to substitute nested variable patterns (e.g., ${varname}) within values by looking them up in the repository, ensuring that complex environment variable references are resolved correctly before being stored.
src/Loader · high confidence
Standardizes development environment with .editorconfig, .gitattributes, and Docker-based tooling
This change introduces foundational configuration files to standardize the project's development environment. A new .editorconfig enforces consistent coding styles (UTF-8, LF line endings, 4-space indentation), while .gitattributes ensures uniform line endings across the repository and excludes non-essential files (tests, docs, CI configs) from distribution archives. Additionally, a Makefile is added to streamline common tasks like running PHPUnit and PHPStan using Docker containers, and the licensing file is standardized to the BSD 3-Clause License.
(repo-wide) · high confidence
Behavioural changes
Introduce Store abstraction for environment loading
The library now uses a dedicated Store layer to handle environment data sources, replacing the previous direct file-reading approach. This change introduces a StoreInterface with two implementations: FileStore, which reads from file paths and supports configurable encodings and short-circuit loading, and StringStore, which handles in-memory strings and automatically strips leading UTF-8 byte order marks. A new StoreBuilder provides a fluent API to configure paths, names, and encoding settings before instantiating the appropriate store, allowing for more flexible and testable environment configuration.
src/Store · high confidence
Introduce adapter-based environment repository with allow-list support
The repository layer has been refactored to use an adapter pattern, introducing \AdapterRepository\ which delegates environment variable operations to pluggable \ReaderInterface\ and \WriterInterface\ implementations. A new \RepositoryBuilder\ allows constructing repositories with custom readers and writers, including support for default adapters like \ServerConstAdapter\ and \EnvConstAdapter\. The builder also introduces an \allowList\ feature for whitelisting environment variable names, replacing previous whitelisting mechanisms. This change provides a more flexible and testable foundation for environment variable management.
src/Repository · high confidence
Refactored file reading and path resolution into dedicated internal classes
The file store implementation has been restructured to improve modularity and encoding handling. A new Paths class now centralizes the logic for resolving full file paths from directory and name arrays, while a new Reader class handles the actual file I/O. The Reader supports arbitrary input file encodings via a new parameter and delegates UTF-8 validation to the Str utility class, throwing an InvalidEncodingException if the content cannot be converted. This change isolates path generation and file reading logic, making the store's file operations more explicit and easier to maintain.
src/Store/File · high confidence
Replaced parser implementation with new architecture using Result types and Unicode support
The parser in src/Parser has been completely rewritten to improve robustness and performance. The new implementation introduces a dedicated Entry class to represent parsed variables and a Value class to handle value content and variable interpolation locations. Parsing logic now utilizes the GrahamCampbell\\ResultType package for explicit error handling instead of throwing exceptions during intermediate steps, and the Lexer has been refactored for better performance. Additionally, variable name validation now supports Unicode characters (via PCRE Unicode properties), and the Lines processor has been updated to correctly handle multiline values while preventing comments from starting them.
src/Parser · high confidence
Reworked environment loading and validation architecture
The library has been refactored to use a modular architecture with separate Store, Parser, Loader, and Repository components, replacing the previous monolithic loading logic. This introduces a new \Validator\ class that allows users to assert environment variables are present, not empty, match specific types (integer, boolean), or fall within allowed values or regex patterns. The \Dotenv\ class now provides factory methods (\create\, \createMutable\, \createImmutable\) to configure the environment repository and loading behavior, including support for multiple file paths, custom encodings, and immutable variable states.
src · high confidence
Test coverage
Added comprehensive test suite for Dotenv loading and validation; Added tests for the .env file store and encoding handling; Added unit tests for repository adapters; Added unit tests for the Dotenv Loader; Added unit tests for the Dotenv parser components; Added unit tests for the environment variable repository; Expanded test fixtures for .env parsing edge cases; Removed legacy test bootstrap file; Removed quoted.env test fixture.
Dependencies
Major dependency overhaul and PHP 8.5 support
The project has been significantly refactored to support PHP 7.2.5 through 8.5, replacing the previous minimal requirements with a modern stack including \ext-pcre\, \graham-campbell/result-type\, \phpoption\, and Symfony polyfills. The main \composer.json\ now uses PSR-4 autoloading, introduces dev dependencies for PHPUnit 8–10 and the \bamarni/composer-bin-plugin\, and adds a \suggest\ for \ext-filter\. Additionally, a new isolated \vendor-bin/phpstan/composer.json\ has been created to pin PHPStan 2.2.9 and its extensions for static analysis, ensuring consistent tooling versions.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.
Score
- CAI 50 → 65 (+15.0)
- Rubric changed (rubric-2026.08.15 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 99 → 98 (-1.0)
- Architecture 94 → 78 (-16.4)
- Maturity 59 → 55 (-4.4)
- Readiness 27 → 62 (+35.3)
- Security 73 → 100 (+27.4)
Resolved (16)
- Coverage not measured — test suite did not build
- Dimension evaluation failed
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- No exposed public API
- No tests found
- Test reliability not included
- The README does not mention how to install or require the package in composer.json. (README.md)
New (75)
- Dependency hygiene PARTLY measured — Composer dependencies read, no committed lock to grade for currency
- Duplicated block (10 lines × 2) (src/Repository/RepositoryBuilder.php)
- Duplicated block (16 lines × 2) (src/Repository/Adapter/EnvConstAdapter.php)
- EntryParser.cutBytes (cognitive 19) (src/Parser/EntryParser.php)
- EntryParser.processToken (cognitive 24) (src/Parser/EntryParser.php)
- EntryParser.processToken (cyclomatic 25) (src/Parser/EntryParser.php)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- Hotspot: src/Parser/EntryParser.php (src/Parser/EntryParser.php)
- …and 55 more
Changes since last survey
- 16 commits — 13 feature/other, 3 fixes
By area
- tests/Dotenv — 5 commits
- (root) — 4 commits
- src/Parser — 3 commits
- src/Repository — 2 commits
- src/Loader — 1 commit
- src/Store — 1 commit
Notable commits
- fix: Add regression tests for existing behaviour (#608)
- fix: Fix memory-safety crash on invalid UTF-8 variable names (#602)
- fix: Fix parsing of export with single character variable names (#599)
- change: Document the real parsing, nesting, comment, escape and validation rules (#609)
- change: Fix formatting of Composer installation command (#589)
- change: Improve diagnostics and messages (#607)
- change: Improve option and result type precision (#613)
- change: Improve parser and loader performance (#600)
- change: PHP 8.6 support (#601)
- change: Remove quadratic value parsing (#604)
- change: Require the covariant option and result types (#612)
- change: Resolve nested variables without re-copying the value prefix (#605)
- change: Resolve the remaining static analysis baseline entries (#614)
- change: Skip environment writes and reads for names or values containing a null byte (#603)
- change: Stop comments from starting multiline values (#615)
- change: Strip a leading UTF-8 byte order mark from string content (#606)
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
vlucas/phpdotenv was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 25 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 301c07936b16d88628b126b01d082ba153cf4c40 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-a9cd699f3cd5.