PHP中環境變量的操作


PHP中環境變量的操作

2021-01-12 硬核項目經理

PHP中環境變量的操作

在 PHP 中,我們可以通過 phpinfo() 查看到當前系統中的環境變量信息(Environment)。在代碼中,我們也可以通過兩個函數,查看和修改相應的環境變量信息。

getenv() 獲取環境變量信息

在不傳參數的情況下,我們可以通過 getenv() 這個函數獲得所有的環境變量信息。不過需要注意的是,在 CLI 環境和 SAPI 環境下它所返回的信息是不一樣的。

print_r(getenv());

// CLI
// Array
// (
//     [USER] => zhangyue
//     [PATH] => /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/VMware Fusion.app/Contents/Public:/Applications/Wireshark.app/Contents/MacOS
//     [LOGNAME] => zhangyue
//     [SSH_AUTH_SOCK] => /private/tmp/com.apple.launchd.h3szqpYfSH/Listeners
//     [HOME] => /Users/zhangyue
//     [SHELL] => /bin/zsh
//     [__CF_USER_TEXT_ENCODING] => 0x1F5:0x19:0x34
//     [TMPDIR] => /var/folders/wj/t2z1cfhs0m9gq48krm8nc0vm0000gn/T/
//     [XPC_SERVICE_NAME] => 0
//     [XPC_FLAGS] => 0x0
//     [OLDPWD] => /Users/zhangyue/MyDoc/博客文章
//     [PWD] => /Users/zhangyue/MyDoc/博客文章/dev-blog/php/202006/source
//     [SHLVL] => 1
//     [TERM_PROGRAM] => vscode
//     [TERM_PROGRAM_VERSION] => 1.45.1
//     [LANG] => en_US.UTF-8
//     [COLORTERM] => truecolor
//     [VSCODE_GIT_IPC_HANDLE] => /var/folders/wj/t2z1cfhs0m9gq48krm8nc0vm0000gn/T/vscode-git-a282fa5813.sock
//     [GIT_ASKPASS] => /Applications/Visual Studio Code.app/Contents/Resources/app/extensions/git/dist/askpass.sh
//     [VSCODE_GIT_ASKPASS_NODE] => /Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper (Renderer).app/Contents/MacOS/Code Helper (Renderer)
//     [VSCODE_GIT_ASKPASS_MAIN] => /Applications/Visual Studio Code.app/Contents/Resources/app/extensions/git/dist/askpass-main.js
//     [TERM] => xterm-256color
//     [_] => /usr/local/bin/php
//     [__KMP_REGISTERED_LIB_9282] => 0x1138dc0f8-cafece1d-libomp.dylib
// )

// SAPI Nginx
// Array
// (
//     [USER] => zhangyue
//     [HOME] => /Users/zhangyue
// )

如果 PHP 在諸如 Fast CGI 之類的 SAPI 中運行,則此函數將始終返回由 SAPI 設置的環境變量的值,即使已使用 putenv() 來設置同名的本地環境變量。這個函數是有兩個參數的,不過它們都是選填的(PHP7以前必須填變量名)。第一個參數是變量名,也就是可以返回具體的某一個環境變量信息。而第二個參數如果設置爲 true 的話,僅返回本地環境變量(由作業系統或 putenv() 設置)。

echo getenv("HOME"), PHP_EOL;
// /Users/zhangyue

// Nginx
print_r($_SERVER);
echo getenv("REQUEST_METHOD"), PHP_EOL; // GET
echo getenv("REQUEST_METHOD", true), PHP_EOL; // 

在第二個參數不爲 true 的情況下,我們可以通過 getenv() 獲得 $_SERVER 、$_ENV 中的所有內容,但是,如果第二個參數爲 true 的話,那麼類似於 Nginx 爲我們添加的那些環境變量就無法獲取了。這就是第二個參數的作用,上面代碼中 REQUEST_METHOD 就是 Nginx 爲我們添加的環境變量,所以第二條輸出語句就不會進行輸出。

putenv() 設置環境變量信息

設置環境變量的函數就比較簡單了,只有一個參數,不過寫法是類似於 Linux 中環境變量的設置寫法。

putenv("A=TestA");
echo getenv("A"), PHP_EOL;
echo getenv("A", true), PHP_EOL;

對於 putenv() 的環境變量,getenv() 的第二個參數設置爲 true 也是可以獲取到的。環境變量僅存活於當前請求期間。在請求結束時環境會恢復到初始狀態。

設置特定的環境變量也有可能是一個潛在的安全漏洞。safe_mode_allowed_env_vars 包含了一個以逗號分隔的前綴列表。在安全模式下,用戶可以僅能修改用該指令設定的前綴名稱的指令。默認情況下,用戶僅能夠修改以 PHP_ 開頭的環境變量(例如 PHP_FOO=BAR)。注意:如果此指令是空的,PHP允許用戶設定任意環境變量!

safe_mode_protected_env_vars 指令包含了逗號分隔的環境變量列表,使用戶最終無法通過 putenv() 修改。即使 safe_mode_allowed_env_vars 設置允許修改,這些變量也會被保護。

所以,在 php.ini 中,默認情況下 putenv() 是定義爲危險函數的,也就是在 disable_functions 中需要刪除掉這個函數才能正常使用,如果要使用 Composer 的話也必須要開啓這個函數才能正常使用。

測試代碼:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202006/source/PHP%E4%B8%AD%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%E7%9A%84%E6%93%8D%E4%BD%9C.php

參考文檔:

https://www.php.net/manual/zh/function.putenv.php

https://www.php.net/manual/zh/function.getenv.php


長按QR碼可將獎勵轉移給我

根據Apple的新政策的要求,iOS的微信上的“獎勵”功能已被禁用。 您仍然可以通過QR碼轉帳資金來獎勵官方帳戶。