У чому різниця між getenv()
і $_ENV
?
Будь-які компроміси між використанням будь-якого?
Я помітив, що іноді getenv()
дає мені те, що мені потрібно, тоді як $_ENV
ні (наприклад HOME
).
У чому різниця між getenv()
і $_ENV
?
Будь-які компроміси між використанням будь-якого?
Я помітив, що іноді getenv()
дає мені те, що мені потрібно, тоді як $_ENV
ні (наприклад HOME
).
Відповіді:
Згідно з php-документацією про getenv , вони абсолютно однакові, за винятком того, що getenv
буде шукати змінну з урахуванням регістру. Здебільшого це, мабуть, не має значення, але один із коментарів до документації пояснює:
Наприклад, у Windows $ _SERVER ['Шлях'] виглядає так, як ви бачите, з першої літери з великої літери, а не з "PATH", як можна було очікувати.
Через це я, мабуть, вирішив би використовувати, getenv
якщо ви не впевнені в регістрі заголовка змінної, яку ви намагаєтесь отримати.
getenv()
перевага: вам не потрібно перевіряти isset
/ empty
перед доступом. getenv()
не видаватиме сповіщень.
Я знаю, що коментар у документах говорить getenv
, що не враховує регістр, але це не така поведінка, яку я спостерігаю:
> 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
Дивлячись на вихідний код для getenv
функції, це відбувається тому , що є три способи , що PHP може принести змінну оточення:
sapi_getenv
(наприклад, якщо він отримує змінну середовища від Apache)GetEnvironmentVariableA
.getenv
функції, наданої libc
.Наскільки я можу зрозуміти, єдиний момент, коли він поводитиметься з урахуванням регістру, - це Windows, оскільки саме так поводиться API змінної середовища Windows. Якщо ви використовуєте Linux, BSD, Mac тощо, getenv
це все одно чує регістр.
Як згадував mario , $_ENV
він не завжди заповнюється через різні конфігурації, variables_order
тому найкраще, якщо ви уникаєте, $_ENV
якщо не контролюєте конфігурацію сервера.
Отже, для найбільш портативного коду PHP:
getenv
.Крім того $_ENV
, зазвичай є порожнім, якщо його variables_order
немає в E
списку. У багатьох налаштуваннях, швидше за все, $_SERVER
заповнюється $_ENV
лише для використання CLI.
З іншого боку, getenv()
безпосередньо отримує доступ до навколишнього середовища.
(Що стосується двозначності випадку, можна було б простіше застосувати array_change_key_case()
.)
Я знайшов getenv()
корисним уникати дивної помилки PHP, де іноді $_SERVER
і $_ENV
був невизначений, якщо auto_globals_jit
був увімкнений (створення змінних _SERVER та _ENV при їх першому використанні). З тих пір я почав цим користуватися.
Взято з документів PHP :
Ця функція корисна (порівняно з
$_SERVER
,$_ENV
), оскільки вона здійснює пошук за ключем $ varname таким чином , не враховуючи регістр масиву. Наприклад, у Windows$_SERVER['Path']
схоже на те, що ви бачите великі літери, а не `PATH
` як ви очікували. Отже просто:<?php getenv('path') ?>
Я б додав, що getenv () - кращий вибір, оскільки, як функцію, він може бути перевантажений для тестування. Тоді як перезапис змінних $ _SERVER або $ _ENV може заважати тестовим фреймворкам та іншим бібліотекам і, зрештою, вимагатиме набагато більше роботи для безпечного виконання.
читати env і створювати
<?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
і$_SERVER
заповнюються даними, отриманими різними способами.getenv()
є ще одним способом доступу до даних, до яких PHP не дозволяє безпосередньо отримати доступ. Він працює навіть зvariables_order = "G"
, коли$_SERVER
і$_ENV
порожні. Прочитайте чудову відповідь Конора Макдермоттро .