diff --git a/CHANGELOG.md b/CHANGELOG.md
index e004ed8..29fa368 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,11 @@
CHANGELOG
=========
+5.4
+---
+
+ * Add `dotenv:dump` command to compile the contents of the .env files into a PHP-optimized file called `.env.local.php`
+
5.1.0
-----
diff --git a/Command/DotenvDumpCommand.php b/Command/DotenvDumpCommand.php
new file mode 100644
index 0000000..43456c8
--- /dev/null
+++ b/Command/DotenvDumpCommand.php
@@ -0,0 +1,128 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Dotenv\Command;
+
+use Symfony\Bundle\FrameworkBundle\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Dotenv\Dotenv;
+
+/**
+ * A console command to compile the contents of the .env files into a PHP-optimized file called .env.local.php.
+ *
+ * @internal
+ */
+final class DotenvDumpCommand extends Command
+{
+ protected static $defaultName = 'dotenv:dump';
+ protected static $defaultDescription = 'Compiles .env files to .env.local.php';
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function configure()
+ {
+ $this
+ ->setDescription('Compiles .env files to .env.local.php.')
+ ->setDefinition([
+ new InputArgument('env', InputArgument::OPTIONAL, 'The application environment to dump .env files for - e.g. "prod".'),
+ ])
+ ->addOption('empty', null, InputOption::VALUE_NONE, 'Ignore the content of .env files')
+ ->setHelp(<<<'EOT'
+The %command.name% command compiles the contents of the .env files into a PHP-optimized file called .env.local.php.
+
+ %command.full_name%
+EOT
+ )
+ ;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output): int
+ {
+ /** @var Application $application */
+ $application = $this->getApplication();
+ $kernel = $application->getKernel();
+
+ if ($env = $input->getArgument('env')) {
+ $_SERVER['APP_ENV'] = $env;
+ }
+
+ $path = $kernel->getProjectDir().'/.env';
+
+ if (!$env || !$input->getOption('empty')) {
+ $vars = $this->loadEnv($path, $env, $kernel->getProjectDir().'/composer.json');
+ $env = $vars['APP_ENV'];
+ }
+
+ if ($input->getOption('empty')) {
+ $vars = ['APP_ENV' => $env];
+ }
+
+ $vars = var_export($vars, true);
+ $vars = <<writeln('Successfully dumped .env files in .env.local.php>');
+
+ return Command::SUCCESS;
+ }
+
+ private function loadEnv(string $path, ?string $env, $composerFilePath): array
+ {
+ $globalsBackup = [$_SERVER, $_ENV];
+ unset($_SERVER['APP_ENV']);
+ $_ENV = ['APP_ENV' => $env];
+ $_SERVER['SYMFONY_DOTENV_VARS'] = implode(',', array_keys($_SERVER));
+ putenv('SYMFONY_DOTENV_VARS='.$_SERVER['SYMFONY_DOTENV_VARS']);
+
+ try {
+ $dotenv = new Dotenv();
+
+ if (!$env && file_exists($p = "$path.local")) {
+ $env = $_ENV['APP_ENV'] = $dotenv->parse(file_get_contents($p), $p)['APP_ENV'] ?? null;
+ }
+
+ if (!$env) {
+ throw new \RuntimeException('Please provide the name of the environment either by passing it as command line argument or by defining the "APP_ENV" variable in the ".env.local" file.');
+ }
+
+ $dotenv->loadEnv(
+ $path,
+ null,
+ 'dev',
+ json_decode(file_get_contents($composerFilePath), true)['extra']['runtime']['test_envs'] ?? ['test']
+ );
+
+ if (isset($_ENV['SYMFONY_DOTENV_VARS'])) {
+ unset($_ENV['SYMFONY_DOTENV_VARS']);
+ }
+ $env = $_ENV;
+ } finally {
+ [$_SERVER, $_ENV] = $globalsBackup;
+ }
+
+ return $env;
+ }
+}
diff --git a/composer.json b/composer.json
index 9bd6cda..89de2c5 100644
--- a/composer.json
+++ b/composer.json
@@ -20,6 +20,8 @@
"symfony/deprecation-contracts": "^2.1"
},
"require-dev": {
+ "symfony/console": "^5.4|^6.0",
+ "symfony/filesystem": "^4.4|^5.0|^6.0",
"symfony/process": "^4.4|^5.0|^6.0"
},
"autoload": {