getenv () contre $ _ENV en PHP

88

Quelle est la différence entre getenv()et $_ENV?

Des compromis entre l'utilisation de l'un ou l'autre?

J'ai remarqué que parfois getenv()me donne ce dont j'ai besoin, alors $_ENVque non (comme HOME).

tau
la source
1
Ne vous laissez pas piéger par PHP qui vous cache les détails sanglants. $_ENVet $_SERVERsont remplis de données obtenues de diverses manières. getenv()est encore un autre moyen d'accéder aux données auxquelles PHP ne vous permet pas d'accéder directement. Cela fonctionne même avec variables_order = "G", quand $_SERVERet $_ENVsont vides. Lisez la grande réponse de Conor McDermottroe .
Palec
Pour ceux qui utilisent le framework Symfony, il existe un cas plus limité de ce qui précède. getenv () retournera toujours la valeur de la variable env telle qu'elle était au démarrage du serveur php, même si elle a été modifiée par la suite. Tandis que $ _ENV [] peut être changé en exécution en modifiant les fichiers .env. Mais bien sûr, cela concerne Symfony, et non PHP en général.
Ross Ivantsiv

Réponses:

59

Selon la documentation php sur getenv , ils sont exactement les mêmes, sauf que getenvchercher la variable d'une manière insensible à la casse. La plupart du temps, cela n'a probablement pas d'importance, mais l'un des commentaires sur la documentation explique:

Par exemple, sur Windows, $ _SERVER ['Path'] est comme vous le voyez, avec la première lettre en majuscule, pas 'PATH' comme vous pouvez vous y attendre.

Pour cette raison, j'opterais probablement pour l'utilisation à getenvmoins que vous ne soyez certain de la casse du titre de la variable que vous essayez de récupérer.

Batkins
la source
15
N'explique pas pourquoi $ _ENV ("FOO") et getenv ("FOO") renvoient des résultats différents.
riche remer
getenv()Avantage supplémentaire : vous n'avez pas besoin de vérifier isset/ emptyavant l'accès. getenv()n'émettra pas d'avis.
Steve Clay
53

Je sais que le commentaire dans la documentation dit que ce getenvn'est pas sensible à la casse, mais ce n'est pas le comportement que je vois:

> 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

En regardant le code source de la getenvfonction, c'est parce que PHP peut récupérer la variable d'environnement de trois manières:

  1. Via sapi_getenv(par exemple, s'il obtient la variable d'environnement d'Apache)
  2. Si sous Windows, à partir de GetEnvironmentVariableA.
  3. Si sous Windows, à partir de la getenvfonction fournie par libc.

Pour autant que je sache, le seul moment où il se comportera de manière insensible à la casse est sous Windows, car c'est ainsi que se comporte l'API de la variable d'environnement Windows. Si vous êtes sous Linux, BSD, Mac, etc., il getenvest toujours sensible à la casse.

Comme mentionné par mario , $_ENVn'est pas toujours peuplé en raison de différentes configurations variables_order, il est donc préférable d'éviter $_ENVsi vous ne contrôlez pas la configuration du serveur.

Donc, pour le code PHP le plus portable:

  1. Utilisez getenv.
  2. Utilisez la casse correcte pour le nom de la variable d'environnement.
Conor McDermottroe
la source
36

De plus, il $_ENVest généralement vide s'il variables_ordern'est pas Erépertorié. Sur de nombreuses configurations, il est probable que seul $_SERVERest rempli et $_ENVest strictement réservé à l'utilisation de la CLI.

D'autre part getenv()accède directement à l'environnement.

(En ce qui concerne l'ambiguïté de cas, on pourrait plus simplement employer array_change_key_case().)

mario
la source
6

J'ai trouvé getenv()utile d'éviter un étrange bogue PHP où parfois $_SERVERet $_ENVn'était pas défini si auto_globals_jitétait activé (création des variables _SERVER et _ENV lors de leur première utilisation). Depuis, j'ai commencé à l'utiliser.

Leopoldo Sanczyk
la source
3

Tiré de la documentation PHP :

Cette fonction est utile (comparée à $_SERVER, $_ENV) car elle recherche la clé $ varname dans ces tableaux de manière insensible à la casse. Par exemple, sous Windows, $_SERVER['Path']c'est comme si vous voyez Capitalisé, pas « PATH» comme vous vous y attendiez. Alors juste:<?php getenv('path') ?>

Ayman Safadi
la source
3

J'ajouterais que getenv () est un meilleur choix car, en tant que fonction, il peut être surchargé à des fins de test. Tandis que l'écrasement de vos variables $ _SERVER ou $ _ENV peut interférer avec les frameworks de test et d'autres bibliothèques et finalement nécessiter beaucoup plus de travail pour être effectué en toute sécurité.

Joe Green
la source
0

lire env et créer

<?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);
    }
}
?>
néoistone inc.
la source