getenv () frente a $ _ENV en PHP

88

¿Cuál es la diferencia entre getenv()y $_ENV?

¿Alguna compensación entre usar cualquiera?

Me di cuenta de que a veces getenv()me da lo que necesito, mientras $_ENVque no (como HOME).

tau
fuente
1
No se deje atrapar por PHP que le oculta los detalles sangrientos. $_ENVy $_SERVERse completan con datos obtenidos de diversas formas. getenv()es otra forma de acceder a los datos a los que PHP no le permite acceder directamente. Funciona incluso con variables_order = "G", cuando $_SERVERy $_ENVestán vacíos. Lea la gran respuesta de Conor McDermottroe .
Palec
Para aquellos que están usando el marco Symfony, hay un caso más limitado de lo anterior. getenv () siempre devolverá el valor de la variable env como estaba cuando se inició el servidor php, incluso si después se cambió. Mientras que $ _ENV [] se puede cambiar en tiempo de ejecución modificando archivos .env. Pero, por supuesto, se relaciona con Symfony y no con PHP en general.
Ross Ivantsiv

Respuestas:

59

De acuerdo con la documentación de php sobre getenv , son exactamente iguales, excepto que getenvbuscarán la variable sin distinción entre mayúsculas y minúsculas. La mayoría de las veces probablemente no importe, pero uno de los comentarios de la documentación explica:

Por ejemplo, en Windows $ _SERVER ['Path'] es como puede ver, con la primera letra en mayúscula, no 'PATH' como cabría esperar.

Debido a eso, probablemente optaría por usarlo a getenvmenos que esté seguro de las mayúsculas y minúsculas del título de la variable que está tratando de recuperar.

Batkins
fuente
15
No explica por qué $ _ENV ("FOO") y getenv ("FOO") devuelven resultados diferentes.
rich remer
getenv()Ventaja adicional : no es necesario verificar isset/ emptyantes del acceso. getenv()no emitirá avisos.
Steve Clay
53

Sé que el comentario en los documentos dice que getenvno distingue entre mayúsculas y minúsculas, pero ese no es el comportamiento que estoy viendo:

> 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

Al observar el código fuente de la getenvfunción, esto se debe a que hay tres formas en que PHP puede obtener la variable de entorno:

  1. Vía sapi_getenv(por ejemplo, si obtiene la variable de entorno de Apache)
  2. Si está en Windows, desde GetEnvironmentVariableA.
  3. Si no es Windows, desde la getenvfunción proporcionada por libc.

Por lo que puedo decir, el único momento en que se comportará de una manera que no distinga entre mayúsculas y minúsculas es en Windows porque así es como se comporta la API de la variable de entorno de Windows. Si está en Linux, BSD, Mac, etc., getenvtodavía distingue entre mayúsculas y minúsculas.

Como mencionó mario , $_ENVno siempre se completa debido a las diferentes configuraciones de, variables_orderpor lo que es mejor si lo evita $_ENVsi no controla la configuración del servidor.

Entonces, para el código PHP más portátil:

  1. Utilice getenv.
  2. Utilice el caso correcto para el nombre de la variable de entorno.
Conor McDermottroe
fuente
36

Además, $_ENVnormalmente está vacío si variables_orderno Eaparece en la lista. En muchas configuraciones, es probable que solo $_SERVERse complete y $_ENVsea ​​estrictamente para uso de CLI.

Por otro lado getenv()accede directamente al entorno.

(En cuanto a la ambigüedad del caso, se podría emplear de forma más sencilla array_change_key_case()).

mario
fuente
6

Encontré getenv()útil para evitar un error extraño de PHP donde a veces $_SERVERy $_ENVno estaba definido si auto_globals_jitestaba habilitado (creando las variables _SERVER y _ENV cuando se usan por primera vez). Desde entonces comencé a usarlo.

Leopoldo Sanczyk
fuente
3

Tomado de los documentos PHP :

Esta función es útil (en comparación con $_SERVER, $_ENV) porque busca la clave $ varname en esos arreglos que no distinguen entre mayúsculas y minúsculas. Por ejemplo, en Windows $_SERVER['Path']es como ver en mayúsculas, no ' PATH' como esperaba. Por lo que sólo:<?php getenv('path') ?>

Ayman Safadi
fuente
3

Agregaría que getenv () es una mejor opción porque, como función, puede sobrecargarse con fines de prueba. Mientras que sobrescribir sus variables $ _SERVER o $ _ENV podría interferir con los marcos de prueba y otras bibliotecas y, en última instancia, requerir mucho más trabajo para llevarse a cabo de manera segura.

Joe Green
fuente
0

leer env y crear

<?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.
fuente