getenv () vs. $ _ENV em PHP

88

Qual é a diferença entre getenv()e $_ENV?

Alguma compensação entre usar um ou outro?

Percebi que às vezes getenv()me dá o que preciso, enquanto $_ENVnão (como HOME).

tau
fonte
1
Não fique preso pelo PHP escondendo os detalhes sangrentos de você. $_ENVe $_SERVERsão preenchidos com dados obtidos de várias maneiras. getenv()é outra forma de acessar dados que o PHP não permite que você acesse diretamente. Funciona mesmo com variables_order = "G", quando $_SERVERe $_ENVestão vazios. Leia a ótima resposta de Conor McDermottroe .
Palec
Para aqueles que estão usando o framework Symfony, há mais um caso limitado acima. getenv () sempre retornará o valor da variável env como era quando o servidor php foi iniciado, mesmo se posteriormente ele foi alterado. Enquanto $ _ENV [] pode ser alterado em tempo de execução modifi cando arquivos .env. Mas é claro que está relacionado ao Symfony, e não ao PHP em geral.
Ross Ivantsiv

Respostas:

59

De acordo com a documentação php sobre getenv , eles são exatamente os mesmos, exceto que getenvirão procurar a variável de uma maneira que não diferencia maiúsculas de minúsculas. Na maioria das vezes, provavelmente não importa, mas um dos comentários na documentação explica:

Por exemplo, no Windows $ _SERVER ['Path'] é como você vê, com a primeira letra maiúscula, não 'PATH' como você pode esperar.

Por causa disso, provavelmente optaria por usar, a getenvmenos que você tenha certeza sobre a capitalização do título da variável que está tentando recuperar.

Batkins
fonte
15
Não explica por que $ _ENV ("FOO") e getenv ("FOO") retornam resultados diferentes.
rich remer de
getenv()Vantagem adicional : você não precisa verificar isset/ emptyantes de acessar. getenv()não emitirá avisos.
Steve Clay,
53

Eu sei que o comentário na documentação diz que não diferencia getenvmaiúsculas de minúsculas, mas esse não é o comportamento que estou vendo:

> env FOO=bar php -r 'print getenv("FOO") . "\n";'
bar
> env FOO=bar php -r 'print getenv("foo") . "\n";'

> env foo=bar php -r 'print getenv("foo") . "\n";'
bar
> env foo=bar php -r 'print getenv("FOO") . "\n";'

> php --version
PHP 5.4.24 (cli) (built: Jan 24 2014 03:51:25)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies

Olhando para o código-fonte da getenvfunção, isso ocorre porque existem três maneiras que o PHP pode buscar a variável de ambiente:

  1. Via sapi_getenv(por exemplo, se está obtendo a variável de ambiente do Apache)
  2. Se estiver no Windows, de GetEnvironmentVariableA.
  3. Se não for Windows, a partir da getenvfunção fornecida por libc.

Pelo que eu posso dizer, o único momento em que ele se comportará de uma maneira que não diferencia maiúsculas de minúsculas é no Windows, porque é assim que a API de variável de ambiente do Windows se comporta. Se você estiver no Linux, BSD, Mac, etc, então getenvainda diferencia maiúsculas de minúsculas.

Como mencionado por mario , $_ENVnem sempre é preenchido devido a configurações diferentes de, variables_orderentão é melhor evitar $_ENVse você não controlar a configuração do servidor.

Portanto, para o código PHP mais portátil:

  1. Use getenv.
  2. Use o caso correto para o nome da variável de ambiente.
Conor McDermottroe
fonte
36

Além disso, $_ENVnormalmente está vazio se variables_ordernão estiver Elistado. Em muitas configurações, é provável que $_SERVERseja apenas preenchido e $_ENVseja estritamente para uso CLI.

Por outro lado, getenv()acessa o ambiente diretamente.

(Em relação à ambiguidade de caso, pode-se empregar de forma mais simples array_change_key_case().)

mario
fonte
6

Achei getenv()útil evitar um bug estranho do PHP onde às vezes $_SERVERe $_ENVera indefinido se auto_globals_jitestava habilitado (criando as variáveis _SERVER e _ENV quando são usadas pela primeira vez). Desde então comecei a usar.

Leopoldo Sanczyk
fonte
3

Retirado dos documentos PHP :

Esta função é útil (comparada com $_SERVER, $_ENV) porque pesquisa a chave $ varname daquela maneira de array que não diferencia maiúsculas de minúsculas. Por exemplo, no Windows $_SERVER['Path']é como ver Capitalizado, não ' PATH' como você esperava. Então apenas:<?php getenv('path') ?>

Ayman Safadi
fonte
3

Eu acrescentaria que getenv () é uma escolha melhor porque, como uma função, pode ser sobrecarregada para fins de teste. Considerando que a substituição de suas variáveis ​​$ _SERVER ou $ _ENV pode interferir com estruturas de teste e outras bibliotecas e, em última análise, exigir muito mais trabalho para ser executado com segurança.

Joe Green
fonte
0

leia env e crie

<?php

namespace neoistone;

class ns_env {
    
    
    /**
     * env to array file storage
     *
     * @param $envPath
     */
    public static function envToArray(string $envPath)
    {
        $variables = [];
        $mread = fopen($envPath, "r");
        $content = fread($mread,filesize($envPath));
        fclose($mread);
        $lines = explode("\n", $content);
        if($lines) {
            foreach($lines as $line) {
                // If not an empty line then parse line
                if($line !== "") {
                    // Find position of first equals symbol
                    $equalsLocation = strpos($line, '=');

                    // Pull everything to the left of the first equals
                    $key = substr($line, 0, $equalsLocation);

                    // Pull everything to the right from the equals to end of the line
                    $value = substr($line, ($equalsLocation + 1), strlen($line));

                    $variables[$key] = $value;

                } else {
                    $variables[] = "";
                }
            }
        }
        return $variables;
    }
  
    /**
     * Array to .env file storage
     *
     * @param $array
     * @param $envPath
     */
    public static function arrayToEnv(array $array, string $envPath)
    {
        $env = "";
        $position = 0;
        foreach($array as $key => $value) {
            $position++;
            // If value isn't blank, or key isn't numeric meaning not a blank line, then add entry
            if($value !== "" || !is_numeric($key)) {
                // If passed in option is a boolean (true or false) this will normally
                // save as 1 or 0. But we want to keep the value as words.
                if(is_bool($value)) {
                    if($value === true) {
                        $value = "true";
                    } else {
                        $value = "false";
                    }
                }

                // Always convert $key to uppercase
                $env .= strtoupper($key) . "=" . $value;

                // If isn't last item in array add new line to end
                if($position != count($array)) {
                   $env .= "\n";
                }
            } else {
                $env .= "\n";
            }
        }
        $mwrite = fopen($envPath, "w");
        fwrite($mwrite, $env);
        fclose($mwrite);
    }
    /**
     * Json to .env file storage
     *
     * @param $json
     * @param $envPath
     */
    public static function JsonToEnv(array $json, string $envPath)
    {
        $env = "";
        $position = 0;
        $array = json_decode($json,true);
        foreach($array as $key => $value) {
            $position++;
            // If value isn't blank, or key isn't numeric meaning not a blank line, then add entry
            if($value !== "" || !is_numeric($key)) {
                // If passed in option is a boolean (true or false) this will normally
                // save as 1 or 0. But we want to keep the value as words.
                if(is_bool($value)) {
                    if($value === true) {
                        $value = "true";
                    } else {
                        $value = "false";
                    }
                }

                // Always convert $key to uppercase
                $env .= strtoupper($key) . "=" . $value;

                // If isn't last item in array add new line to end
                if($position != count($array)) {
                   $env .= "\n";
                }
            } else {
                $env .= "\n";
            }
        }
        $mwrite = fopen($envPath, "w");
        fwrite($mwrite, $env);
        fclose($mwrite);
    }
    /**
     * XML to .env file storage
     *
     * @param $json
     * @param $envPath
     */
    public static function XmlToEnv(array $xml, string $envPath)
    {
        $env = "";
        $position = 0;
        $array = simplexml_load_string($xml);
        foreach($array as $key => $value) {
            $position++;
            // If value isn't blank, or key isn't numeric meaning not a blank line, then add entry
            if($value !== "" || !is_numeric($key)) {
                // If passed in option is a boolean (true or false) this will normally
                // save as 1 or 0. But we want to keep the value as words.
                if(is_bool($value)) {
                    if($value === true) {
                        $value = "true";
                    } else {
                        $value = "false";
                    }
                }

                // Always convert $key to uppercase
                $env .= strtoupper($key) . "=" . $value;

                // If isn't last item in array add new line to end
                if($position != count($array)) {
                   $env .= "\n";
                }
            } else {
                $env .= "\n";
            }
        }
        $mwrite = fopen($envPath, "w");
        fwrite($mwrite, $env);
        fclose($mwrite);
    }
}
?>
neoistone inc.
fonte