From 13048bee97771f9c2f4cb5d40dd68e9955a54325 Mon Sep 17 00:00:00 2001 From: Toto Date: Thu, 10 Jul 2025 13:35:35 +0700 Subject: [PATCH 1/7] feat: add environment directory to load .env file --- app/Config/Paths.php | 10 ++++++++++ system/Boot.php | 2 +- system/Commands/Encryption/GenerateKey.php | 5 +++-- system/Commands/Utilities/Environment.php | 5 +++-- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/app/Config/Paths.php b/app/Config/Paths.php index 3dc9c5d93951..16dc37068660 100644 --- a/app/Config/Paths.php +++ b/app/Config/Paths.php @@ -75,4 +75,14 @@ class Paths * is used when no value is provided to `Services::renderer()`. */ public string $viewDirectory = __DIR__ . '/../Views'; + + /** + * --------------------------------------------------------------- + * ENVIRONMENT DIRECTORY NAME + * --------------------------------------------------------------- + * + * This variable must contain the name of the directory for + * environment files. + */ + public string $environmentDirectory = __DIR__ . '/../../'; } diff --git a/system/Boot.php b/system/Boot.php index ba3675516b16..283a61bd4769 100644 --- a/system/Boot.php +++ b/system/Boot.php @@ -170,7 +170,7 @@ public static function preload(Paths $paths): void protected static function loadDotEnv(Paths $paths): void { require_once $paths->systemDirectory . '/Config/DotEnv.php'; - (new DotEnv($paths->appDirectory . '/../'))->load(); + (new DotEnv($paths->environmentDirectory))->load(); } protected static function defineEnvironment(): void diff --git a/system/Commands/Encryption/GenerateKey.php b/system/Commands/Encryption/GenerateKey.php index a3fdbd4393a9..3f90203c7d9c 100644 --- a/system/Commands/Encryption/GenerateKey.php +++ b/system/Commands/Encryption/GenerateKey.php @@ -17,6 +17,7 @@ use CodeIgniter\CLI\CLI; use CodeIgniter\Config\DotEnv; use CodeIgniter\Encryption\Encryption; +use Config\Paths; /** * Generates a new encryption key. @@ -101,7 +102,7 @@ public function run(array $params) // force DotEnv to reload the new env vars putenv('encryption.key'); unset($_ENV['encryption.key'], $_SERVER['encryption.key']); - $dotenv = new DotEnv(ROOTPATH); + $dotenv = new DotEnv((new Paths())->environmentDirectory); $dotenv->load(); CLI::write('Application\'s new encryption key was successfully set.', 'green'); @@ -155,7 +156,7 @@ protected function confirmOverwrite(array $params): bool protected function writeNewEncryptionKeyToFile(string $oldKey, string $newKey): bool { $baseEnv = ROOTPATH . 'env'; - $envFile = ROOTPATH . '.env'; + $envFile = (new Paths())->environmentDirectory . '.env'; if (! is_file($envFile)) { if (! is_file($baseEnv)) { diff --git a/system/Commands/Utilities/Environment.php b/system/Commands/Utilities/Environment.php index 22794fe9d51d..f5caad4ba3f4 100644 --- a/system/Commands/Utilities/Environment.php +++ b/system/Commands/Utilities/Environment.php @@ -16,6 +16,7 @@ use CodeIgniter\CLI\BaseCommand; use CodeIgniter\CLI\CLI; use CodeIgniter\Config\DotEnv; +use Config\Paths; /** * Command to display the current environment, @@ -119,7 +120,7 @@ public function run(array $params) // however we cannot redefine the ENVIRONMENT constant putenv('CI_ENVIRONMENT'); unset($_ENV['CI_ENVIRONMENT'], $_SERVER['CI_ENVIRONMENT']); - (new DotEnv(ROOTPATH))->load(); + (new DotEnv((new Paths())->environmentDirectory))->load(); CLI::write(sprintf('Environment is successfully changed to "%s".', $env), 'green'); CLI::write('The ENVIRONMENT constant will be changed in the next script execution.'); @@ -134,7 +135,7 @@ public function run(array $params) private function writeNewEnvironmentToEnvFile(string $newEnv): bool { $baseEnv = ROOTPATH . 'env'; - $envFile = ROOTPATH . '.env'; + $envFile = (new Paths())->environmentDirectory . '.env'; if (! is_file($envFile)) { if (! is_file($baseEnv)) { From 6df2af8e7783f1b13b6fff8d60c5dc084357a641 Mon Sep 17 00:00:00 2001 From: Toto Date: Tue, 15 Jul 2025 08:33:06 +0700 Subject: [PATCH 2/7] fix: rename environment directory variable from environmentDirectory to envDirectory Co-authored-by: Michal Sniatala --- app/Config/Paths.php | 2 +- system/Boot.php | 2 +- system/Commands/Encryption/GenerateKey.php | 4 ++-- system/Commands/Utilities/Environment.php | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/Config/Paths.php b/app/Config/Paths.php index 16dc37068660..cf2fcfca880b 100644 --- a/app/Config/Paths.php +++ b/app/Config/Paths.php @@ -84,5 +84,5 @@ class Paths * This variable must contain the name of the directory for * environment files. */ - public string $environmentDirectory = __DIR__ . '/../../'; + public string $envDirectory = __DIR__ . '/../../'; } diff --git a/system/Boot.php b/system/Boot.php index 283a61bd4769..4b8292796a97 100644 --- a/system/Boot.php +++ b/system/Boot.php @@ -170,7 +170,7 @@ public static function preload(Paths $paths): void protected static function loadDotEnv(Paths $paths): void { require_once $paths->systemDirectory . '/Config/DotEnv.php'; - (new DotEnv($paths->environmentDirectory))->load(); + (new DotEnv($paths->envDirectory))->load(); } protected static function defineEnvironment(): void diff --git a/system/Commands/Encryption/GenerateKey.php b/system/Commands/Encryption/GenerateKey.php index 3f90203c7d9c..4c7beda0095d 100644 --- a/system/Commands/Encryption/GenerateKey.php +++ b/system/Commands/Encryption/GenerateKey.php @@ -102,7 +102,7 @@ public function run(array $params) // force DotEnv to reload the new env vars putenv('encryption.key'); unset($_ENV['encryption.key'], $_SERVER['encryption.key']); - $dotenv = new DotEnv((new Paths())->environmentDirectory); + $dotenv = new DotEnv((new Paths())->envDirectory); $dotenv->load(); CLI::write('Application\'s new encryption key was successfully set.', 'green'); @@ -156,7 +156,7 @@ protected function confirmOverwrite(array $params): bool protected function writeNewEncryptionKeyToFile(string $oldKey, string $newKey): bool { $baseEnv = ROOTPATH . 'env'; - $envFile = (new Paths())->environmentDirectory . '.env'; + $envFile = (new Paths())->envDirectory . '.env'; if (! is_file($envFile)) { if (! is_file($baseEnv)) { diff --git a/system/Commands/Utilities/Environment.php b/system/Commands/Utilities/Environment.php index f5caad4ba3f4..5e063de357e8 100644 --- a/system/Commands/Utilities/Environment.php +++ b/system/Commands/Utilities/Environment.php @@ -120,7 +120,7 @@ public function run(array $params) // however we cannot redefine the ENVIRONMENT constant putenv('CI_ENVIRONMENT'); unset($_ENV['CI_ENVIRONMENT'], $_SERVER['CI_ENVIRONMENT']); - (new DotEnv((new Paths())->environmentDirectory))->load(); + (new DotEnv((new Paths())->envDirectory))->load(); CLI::write(sprintf('Environment is successfully changed to "%s".', $env), 'green'); CLI::write('The ENVIRONMENT constant will be changed in the next script execution.'); @@ -135,7 +135,7 @@ public function run(array $params) private function writeNewEnvironmentToEnvFile(string $newEnv): bool { $baseEnv = ROOTPATH . 'env'; - $envFile = (new Paths())->environmentDirectory . '.env'; + $envFile = (new Paths())->envDirectory . '.env'; if (! is_file($envFile)) { if (! is_file($baseEnv)) { From d2d2ab66ac7d6d59d5d9103fb721d50ac6e4e175 Mon Sep 17 00:00:00 2001 From: Toto Date: Tue, 15 Jul 2025 08:41:27 +0700 Subject: [PATCH 3/7] docs: add information about changing .env file location Co-authored-by: Michal Sniatala --- .../source/general/managing_apps.rst | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/user_guide_src/source/general/managing_apps.rst b/user_guide_src/source/general/managing_apps.rst index 35a30153d034..6b847889bb4b 100644 --- a/user_guide_src/source/general/managing_apps.rst +++ b/user_guide_src/source/general/managing_apps.rst @@ -97,3 +97,26 @@ of those: .. literalinclude:: managing_apps/004.php Only when you change the Application Directory, see :ref:`renaming-app-directory` and modify the paths in the **index.php** and **spark**. + +Changing the Location of the .env File +====================================== + +If necessary, you can change the location of the ``.env`` file by adjusting the ``$envDirectory`` +property in ``app/Config/Paths.php``. + +By default, the framework loads environment settings from a ``.env`` file located one level above +the ``app/`` directory (in the ``ROOTPATH``). This is a safe location when your domain is correctly +pointed to the ``public/`` directory, as recommended. + +In practice, however, some applications are served from a subdirectory (e.g., ``http://example.com/myapp``) +rather than from the main domain. In such cases, placing the ``.env`` file within the ``ROOTPATH`` may expose +sensitive configuration if ``.htaccess`` or other protections are misconfigured. + +To avoid this risk in such setups, it is recommended to ensure the ``.env`` file is located outside any +web-accessible directories. + +.. warning:: + + If you change the location of the ``.env`` file, make absolutely sure it is not publicly accessible. + Exposure of this file could lead to compromised credentials and access to critical services, such as your + database, mail server, or third-party APIs. From 2f14af3f299a5307890e69f0b59d24f9d4186746 Mon Sep 17 00:00:00 2001 From: Toto Date: Tue, 15 Jul 2025 08:49:35 +0700 Subject: [PATCH 4/7] fix: improve environment variable loading with fallback to ROOTPATH --- system/Boot.php | 3 ++- system/Commands/Encryption/GenerateKey.php | 4 ++-- system/Commands/Utilities/Environment.php | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/system/Boot.php b/system/Boot.php index 4b8292796a97..5b228664146f 100644 --- a/system/Boot.php +++ b/system/Boot.php @@ -170,7 +170,8 @@ public static function preload(Paths $paths): void protected static function loadDotEnv(Paths $paths): void { require_once $paths->systemDirectory . '/Config/DotEnv.php'; - (new DotEnv($paths->envDirectory))->load(); + $envDirectory = $paths->envDirectory ?? $paths->appDirectory . '/../'; + (new DotEnv($envDirectory))->load(); } protected static function defineEnvironment(): void diff --git a/system/Commands/Encryption/GenerateKey.php b/system/Commands/Encryption/GenerateKey.php index 4c7beda0095d..b34b422f7bfe 100644 --- a/system/Commands/Encryption/GenerateKey.php +++ b/system/Commands/Encryption/GenerateKey.php @@ -102,7 +102,7 @@ public function run(array $params) // force DotEnv to reload the new env vars putenv('encryption.key'); unset($_ENV['encryption.key'], $_SERVER['encryption.key']); - $dotenv = new DotEnv((new Paths())->envDirectory); + $dotenv = new DotEnv((new Paths())->envDirectory ?? ROOTPATH); $dotenv->load(); CLI::write('Application\'s new encryption key was successfully set.', 'green'); @@ -156,7 +156,7 @@ protected function confirmOverwrite(array $params): bool protected function writeNewEncryptionKeyToFile(string $oldKey, string $newKey): bool { $baseEnv = ROOTPATH . 'env'; - $envFile = (new Paths())->envDirectory . '.env'; + $envFile = ((new Paths())->envDirectory ?? ROOTPATH) . '.env'; if (! is_file($envFile)) { if (! is_file($baseEnv)) { diff --git a/system/Commands/Utilities/Environment.php b/system/Commands/Utilities/Environment.php index 5e063de357e8..0c3730631f42 100644 --- a/system/Commands/Utilities/Environment.php +++ b/system/Commands/Utilities/Environment.php @@ -120,7 +120,7 @@ public function run(array $params) // however we cannot redefine the ENVIRONMENT constant putenv('CI_ENVIRONMENT'); unset($_ENV['CI_ENVIRONMENT'], $_SERVER['CI_ENVIRONMENT']); - (new DotEnv((new Paths())->envDirectory))->load(); + (new DotEnv((new Paths())->envDirectory ?? ROOTPATH))->load(); CLI::write(sprintf('Environment is successfully changed to "%s".', $env), 'green'); CLI::write('The ENVIRONMENT constant will be changed in the next script execution.'); @@ -135,7 +135,7 @@ public function run(array $params) private function writeNewEnvironmentToEnvFile(string $newEnv): bool { $baseEnv = ROOTPATH . 'env'; - $envFile = (new Paths())->envDirectory . '.env'; + $envFile = (new Paths())->envDirectory ?? ROOTPATH . '.env'; if (! is_file($envFile)) { if (! is_file($baseEnv)) { From cedc5688ebabec2f45076977c99e79aee4b557bd Mon Sep 17 00:00:00 2001 From: Toto Date: Tue, 15 Jul 2025 13:26:12 +0700 Subject: [PATCH 5/7] fix: dynamic path for .env file Co-authored-by: Michal Sniatala --- system/Commands/Utilities/Environment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Commands/Utilities/Environment.php b/system/Commands/Utilities/Environment.php index 0c3730631f42..99a90415ceea 100644 --- a/system/Commands/Utilities/Environment.php +++ b/system/Commands/Utilities/Environment.php @@ -135,7 +135,7 @@ public function run(array $params) private function writeNewEnvironmentToEnvFile(string $newEnv): bool { $baseEnv = ROOTPATH . 'env'; - $envFile = (new Paths())->envDirectory ?? ROOTPATH . '.env'; + $envFile = ((new Paths())->envDirectory ?? ROOTPATH) . '.env'; if (! is_file($envFile)) { if (! is_file($baseEnv)) { From a601c2c31b7da683a029d100ce35eb32dac63de1 Mon Sep 17 00:00:00 2001 From: Toto Date: Mon, 21 Jul 2025 15:05:57 +0700 Subject: [PATCH 6/7] fix: improve wording for .env file location recommendation Co-authored-by: John Paul E. Balandan, CPA Co-authored-by: Michal Sniatala Co-authored-by: ddevsr <97607754+ddevsr@users.noreply.github.com> --- app/Config/Paths.php | 6 ++++-- user_guide_src/source/general/managing_apps.rst | 5 ++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/Config/Paths.php b/app/Config/Paths.php index cf2fcfca880b..61010e10355a 100644 --- a/app/Config/Paths.php +++ b/app/Config/Paths.php @@ -81,8 +81,10 @@ class Paths * ENVIRONMENT DIRECTORY NAME * --------------------------------------------------------------- * - * This variable must contain the name of the directory for - * environment files. + * This variable must contain the name of the directory where + * the .env file is located. + * Please consider security implications when changing this + * value - the directory should not be publicly accessible. */ public string $envDirectory = __DIR__ . '/../../'; } diff --git a/user_guide_src/source/general/managing_apps.rst b/user_guide_src/source/general/managing_apps.rst index 6b847889bb4b..5e71840a98bf 100644 --- a/user_guide_src/source/general/managing_apps.rst +++ b/user_guide_src/source/general/managing_apps.rst @@ -110,10 +110,9 @@ pointed to the ``public/`` directory, as recommended. In practice, however, some applications are served from a subdirectory (e.g., ``http://example.com/myapp``) rather than from the main domain. In such cases, placing the ``.env`` file within the ``ROOTPATH`` may expose -sensitive configuration if ``.htaccess`` or other protections are misconfigured. +sensitive configuration data if ``.htaccess`` or other protections are misconfigured. -To avoid this risk in such setups, it is recommended to ensure the ``.env`` file is located outside any -web-accessible directories. +To avoid this risk in such setups, it is recommended that you ensure the ``.env`` file is located outside any web-accessible directories. .. warning:: From 8b146beb80527173d5164a3e043495e5c3e06f9d Mon Sep 17 00:00:00 2001 From: Toto Date: Sun, 27 Jul 2025 18:34:12 +0700 Subject: [PATCH 7/7] docs(chngelog): add support for changing the location of the .env file via Paths::$envDirectory property --- user_guide_src/source/changelogs/v4.7.0.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/user_guide_src/source/changelogs/v4.7.0.rst b/user_guide_src/source/changelogs/v4.7.0.rst index c3d9cd1d5c12..843f1f393533 100644 --- a/user_guide_src/source/changelogs/v4.7.0.rst +++ b/user_guide_src/source/changelogs/v4.7.0.rst @@ -101,6 +101,7 @@ Changes - **Cookie:** The ``CookieInterface::EXPIRES_FORMAT`` has been changed to ``D, d M Y H:i:s \G\M\T`` to follow the recommended format in RFC 7231. - **Format:** Added support for configuring ``json_encode()`` maximum depth via ``Config\Format::$jsonEncodeDepth``. +- **Paths:** Added support for changing the location of the ``.env`` file via the ``Paths::$envDirectory`` property. ************ Deprecations