Jaka jest różnica między getenv()
i $_ENV
?
Czy są jakieś kompromisy między używaniem któregokolwiek z nich?
Zauważyłem, że czasami getenv()
daje mi to, czego potrzebuję, a $_ENV
nie (np. HOME
).
Jaka jest różnica między getenv()
i $_ENV
?
Czy są jakieś kompromisy między używaniem któregokolwiek z nich?
Zauważyłem, że czasami getenv()
daje mi to, czego potrzebuję, a $_ENV
nie (np. HOME
).
Odpowiedzi:
Zgodnie z dokumentacją php dotyczącą getenv , są one dokładnie takie same, z tym wyjątkiem, że getenv
będą szukać zmiennej bez rozróżniania wielkości liter. W większości przypadków prawdopodobnie nie ma to znaczenia, ale jeden z komentarzy do dokumentacji wyjaśnia:
Na przykład w systemie Windows $ _SERVER ['Path'] jest jak widać, z pierwszą literą wielką, a nie 'PATH', jak można by się spodziewać.
Z tego powodu prawdopodobnie zdecydowałbym się użyć, getenv
chyba że masz pewność co do wielkości liter w tytule zmiennej, którą próbujesz pobrać.
getenv()
zaleta: nie musisz sprawdzać isset
/ empty
przed dostępem. getenv()
nie będzie emitować powiadomień.
Wiem, że komentarz w dokumentacji mówi, że wielkość getenv
liter nie jest rozróżniana, ale to nie jest zachowanie, które widzę:
> 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
Patrząc na kod źródłowy dla getenv
funkcji, to dlatego, że istnieją trzy sposoby, że PHP może pobrać zmienną środowiskową:
sapi_getenv
(np. Jeśli pobiera zmienną środowiskową z Apache)GetEnvironmentVariableA
.getenv
funkcji dostarczonej przez libc
.O ile wiem, jedyny moment, w którym zachowuje się bez rozróżniania wielkości liter, występuje w systemie Windows, ponieważ tak zachowuje się zmienna środowiskowa Windows API. Jeśli używasz Linuksa, BSD, Maca itp., getenv
Nadal jest rozróżniana wielkość liter.
Jak wspomniano w mario , $_ENV
nie zawsze jest wypełniony ze względu na różne konfiguracje, variables_order
więc najlepiej tego unikać, $_ENV
jeśli nie kontrolujesz konfiguracji serwera.
Tak więc dla najbardziej przenośnego kodu PHP:
getenv
.Dodatkowo $_ENV
jest zwykle pusty, jeśli variables_order
nie ma na E
liście. W wielu konfiguracjach jest prawdopodobne, że $_SERVER
jest wypełniony tylko i $_ENV
jest przeznaczony wyłącznie do użytku z interfejsem CLI.
Z drugiej strony getenv()
ma bezpośredni dostęp do środowiska.
(Jeśli chodzi o niejednoznaczność przypadku, można prościej zastosować array_change_key_case()
.)
Znalazłem getenv()
przydatna uniknąć dziwny PHP bug gdzie czasem $_SERVER
i $_ENV
została zdefiniowana jeśli auto_globals_jit
została włączona (tworzenie _SERVER i _ENV zmienne kiedy jesteś po raz pierwszy użyty). Od tego czasu zacząłem go używać.
Zaczerpnięte z dokumentacji PHP :
Ta funkcja jest użyteczna (w porównaniu do
$_SERVER
,$_ENV
), ponieważ przeszukuje klucz $ varname w sposób bez uwzględniania wielkości liter. Na przykład w systemie Windows$_SERVER['Path']
wygląda tak, jakbyś widział wielkie litery, a nie „PATH
”, jak się spodziewałeś. Więc tylko:<?php getenv('path') ?>
Dodam, że getenv () jest lepszym wyborem, ponieważ jako funkcja może być przeciążona do celów testowych. Podczas gdy nadpisywanie zmiennych $ _SERVER lub $ _ENV może kolidować z frameworkami testowymi i innymi bibliotekami i ostatecznie wymagać dużo więcej pracy, aby je bezpiecznie przeprowadzić.
przeczytaj env i utwórz
<?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);
}
}
?>
$_ENV
i$_SERVER
są wypełnione danymi uzyskanymi na różne sposoby.getenv()
to kolejny sposób uzyskiwania dostępu do danych, do których PHP nie umożliwia bezpośredniego dostępu. Działa nawet zvariables_order = "G"
, kiedy$_SERVER
i$_ENV
są puste. Przeczytaj świetną odpowiedź Conora McDermottroe .