PHP的getenv函数总是返回false

6
getenv()始终返回false。我正在使用Symfony dotenv库,并从项目根目录中的.env文件加载变量。 getenv() 函数总是返回 false。我正在使用 Symfony dotenv 库,从位于我的项目根目录下的 .env 文件中加载变量。
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\Dotenv\Exception\PathException;

if (!getenv('APP_ENV')) {
    try {
        (new Dotenv())->load(__DIR__ . '/../.env');
    } catch (PathException $ex) {
        echo $ex->getMessage();
        exit(1);
    }
}

var_dump(getenv('APP_ENV')); // bool(false)

但是当我倾倒超级全局变量时,我可以看到我的变量

var_dump($_ENV); // array:1["APP_ENV" => "dev"]

那么我错过了什么?


2
这个回答解决了你的问题吗?无法读取环境变量 - Chaz
1
$dotenv = new Dotenv(true); - vishalknishad
4个回答

15

虽然我没有使用Symfony,但我遇到了相同的问题。我正在使用vlucas库,以下是导致问题的第一段代码:

define('BASE_PATH',realpath(__DIR__.'/../../'));
require_once __DIR__.'/../../vendor/autoload.php';
$dotEnv = Dotenv\Dotenv::createImmutable(BASE_PATH);
$dotEnv->load();
$appName=$_ENV['APP_NAME'];
$appName2=getenv('APP_NAME');

var_dump($appName) // return "This is my website";
var_dump($appName2) // return false;

一开始我不知道问题出在哪里,但似乎是因为putenv()和getenv()不是线程安全的。

所以我将代码改为:

define('BASE_PATH',realpath(__DIR__.'/../../'));
require_once __DIR__.'/../../vendor/autoload.php';
$dotEnv = Dotenv\Dotenv::createUnsafeImmutable(BASE_PATH);// <======== :) look here
$dotEnv->load();
$appName=$_ENV['APP_NAME'];
$appName2=getenv('APP_NAME');

var_dump($appName) // return "This is my website";
var_dump($appName2) // return "This is my website";

我希望这可以解决您的问题。


谢谢,对我有用。但是你能解释一下为什么吗?或者你有任何学习相关的链接吗? - Nur Muhammad

10

对于Symfony 5.x+,在public/index.php中

替换

(new Dotenv())->bootEnv(dirname(__DIR__).'/.env');

使用

(new Dotenv())->usePutenv()->bootEnv(dirname(__DIR__).'/.env');

这对我有效。


5

默认情况下,Symfony不使用putenv()函数(我认为这是出于安全考虑,但不确定),因此如果您正在使用Symfony的“伪”环境变量,则无法直接使用getenv()函数。

在我看来,最好的解决方案是改用依赖注入。您可以在Symfony配置中访问环境变量。例如,使用yaml配置文件:

framework:
    secret: '%env(APP_SECRET)%'

如果您仍想使用getenv(),我不建议这样做,有多个原因。但是,如果您确实需要使用它,可以按照以下步骤操作:
  • Symfony 5.1及以前版本:在config/bootstrap.php文件中添加 -> new Dotenv(true)
  • Symfony 5.1及以后版本:在public/index.php文件中,在Dotenv实例化之前添加以下内容 -> Dotenv::usePutenv();

编辑:

  • 使用putenv PHP函数不是线程安全的,这就是为令该设置默认为false的原因。
  • 我一开始没有注意到您正在使用Dotenv组件作为独立库,因此您可以忽略我关于依赖注入的建议。

0

原因是由于使用getenv()和putenv()函数不是线程安全的,因此强烈不建议使用这些函数。但是,仍然可以通过指示PHP dotenv使用这些函数来实现。可以调用Dotenv::createUnsafeImmutable而不是调用Dotenv::createImmutable,这将在后台添加PutenvAdapter。现在,您的环境变量将可通过getenv方法和超级全局变量使用:

$s3_bucket = getenv('S3_BUCKET');
$s3_bucket = $_ENV['S3_BUCKET'];
$s3_bucket = $_SERVER['S3_BUCKET'];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接