getenv () contro $ _ENV in PHP


88

Qual è la differenza tra getenv()e$_ENV ?

Qualche compromesso tra l'utilizzo di entrambi?

Ho notato che a volte getenv()mi dà ciò di cui ho bisogno, mentre $_ENVnon lo fa (come HOME).


1
Non farti intrappolare da PHP che ti nasconde i dettagli cruenti. $_ENVe $_SERVERsono popolati con dati ottenuti in vari modi. getenv()è ancora un altro modo per accedere ai dati a cui PHP non ti consente di accedere direttamente. Funziona anche con variables_order = "G", quando $_SERVERe $_ENVsono vuoti. Leggi l'ottima risposta di Conor McDermottroe .
Palec


Per coloro che usano il framework Symfony, c'è un altro caso limitato di quanto sopra. getenv () restituirà sempre il valore della variabile env com'era all'avvio del server php, anche se in seguito è stato modificato. Mentre $ _ENV [] può essere cambiato in runtime modificando i file .env. Ma ovviamente si riferisce a Symfony e non a PHP in generale.
Ross Ivantsiv

Risposte:


60

Secondo la documentazione di php su getenv , sono esattamente gli stessi, tranne per il fatto che getenvcercheranno la variabile senza distinzione tra maiuscole e minuscole. Il più delle volte probabilmente non ha importanza, ma uno dei commenti sulla documentazione spiega:

Ad esempio su Windows $ _SERVER ['Path'] è come vedi, con la prima lettera maiuscola, non 'PATH' come potresti aspettarti.

Per questo motivo, probabilmente sceglierei di utilizzare a getenvmeno che tu non sia sicuro dell'involucro del titolo della variabile che stai cercando di recuperare.


15
Non spiega perché $ _ENV ("FOO") e getenv ("FOO") restituiscono risultati diversi.
Rich remer il

getenv()Vantaggio aggiunto : non è necessario controllare isset/ emptyprima dell'accesso. getenv()non emetterà avvisi.
Steve Clay

53

So che il commento nei documenti dice che non getenvfa distinzione tra maiuscole e minuscole, ma non è questo il comportamento che vedo:

> 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

Guardando il codice sorgente della getenvfunzione, questo perché ci sono tre modi in cui PHP può recuperare la variabile d'ambiente:

  1. Via sapi_getenv(ad esempio, se sta ottenendo la variabile d'ambiente da Apache)
  2. Se su Windows, da GetEnvironmentVariableA .
  3. Se su non Windows, dalla getenvfunzione fornita da libc.

Per quanto ne so, l'unica volta in cui si comporterà senza distinzione tra maiuscole e minuscole è su Windows perché è così che si comporta l'API della variabile di ambiente di Windows. Se sei su Linux, BSD, Mac, ecc., Fa getenvancora distinzione tra maiuscole e minuscole.

Come accennato da mario , $_ENVnon è sempre popolato a causa di diverse configurazioni di variables_orderquindi è meglio se lo eviti $_ENVse non controlli la configurazione del server.

Quindi, per il codice PHP più portatile:

  1. Usa getenv.
  2. Usa il caso corretto per il nome della variabile di ambiente.

39

Inoltre $_ENVè in genere vuoto se non variables_orderè Eelencato. Su molte configurazioni è probabile che sia solo $_SERVERpopolato ed $_ENVè strettamente per l'utilizzo della CLI.

D'altra parte getenv()accede direttamente all'ambiente.

(Per quanto riguarda l'ambiguità del caso, si potrebbe utilizzare più semplicemente array_change_key_case().)


6

Ho trovato getenv()utile per evitare uno strano bug PHP dove a volte $_SERVERed $_ENVera indefinito se auto_globals_jitera abilitato (creando le variabili _SERVER e _ENV quando vengono utilizzate per la prima volta). Da allora ho iniziato ad usarlo.


3

Tratto dalla documentazione PHP :

Questa funzione è utile (rispetto a $_SERVER, $_ENV) perché cerca la chiave $ varname in quel modo array senza distinzione tra maiuscole e minuscole. Ad esempio su Windows $_SERVER['Path']è come se vedessi maiuscolo, non " PATH" come ti aspettavi. Quindi:<?php getenv('path') ?>


3

Aggiungerei che getenv () è una scelta migliore perché, come funzione, può essere sovraccaricato a scopo di test. Mentre la sovrascrittura delle variabili $ _SERVER o $ _ENV potrebbe interferire con i framework di test e altre librerie e alla fine richiedere molto più lavoro per essere eseguita in sicurezza.


-1

leggi env e crea

<?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);
    }
}
?>

Cosa c'entra questo con la domanda reale?
Cyclonecode
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.