CLI下php -v可查版本,php --ini显示实际加载的php.ini路径,which php或where php定位二进制文件;$_ENV默认为空是安全设计,应统一用getenv()读取环境变量,它不依赖配置、大小写敏感、支持运行时putenv()新增变量。

CLI 下 php -v 能直接看到版本,但环境变量必须用 getenv() 读,$_ENV 默认为空——这不是 bug,是 PHP 的安全默认行为。
怎么快速确认当前 CLI 使用的 PHP 版本和配置路径
别猜,直接敲命令。终端里运行:php -v 输出主版本、构建时间、Zend 引擎版本;php --ini 显示它实际加载了哪个 php.ini(注意不是你编辑的那个);which php(Linux/macOS)或 where php(Windows)定位二进制文件位置。
常见错误现象:改了 /etc/php/8.2/cli/php.ini 却没生效,结果发现 php --ini 显示加载的是 /usr/local/etc/php/8.2/php.ini ——多版本共存时路径容易错乱。
多个要点、条件或步骤请使用无序列表呈现:
立即学习“PHP免费学习笔记(深入)”;
-
php -v和php --version效果一致,但后者输出更简洁 -
php -i | grep "Loaded Configuration File"可精准提取 ini 路径 - Web 服务器用的 PHP 版本和 CLI 是两套,
phpinfo()只反映 Web 环境
为什么 $_ENV 在 CLI 里总是空数组
因为 PHP CLI SAPI 默认不填充 $_ENV,除非你在 php.ini 里显式设置 variables_order = "EGPCS"(E 表示 environment)。但这不是推荐做法——它依赖配置,且无法反映运行时通过 putenv() 新增的变量。
真正可靠的是 getenv():它绕过 $_ENV 初始化逻辑,直接读取操作系统进程环境块,不受 variables_order 影响。
多个要点、条件或步骤请使用无序列表呈现:
立即学习“PHP免费学习笔记(深入)”;
-
getenv('DB_HOST')返回字符串,getenv('MISSING')返回false(不是null或空串) - 大小写敏感:Linux/macOS 下
getenv('PATH')有效,getenv('path')返回false -
putenv('FOO=bar')后,getenv('FOO')立即可读,但$_ENV['FOO']仍为空
如何让 CLI 脚本在任意目录下像系统命令一样运行
核心是把脚本所在目录加进 $PATH。比如你写了个 deploy.php,想在哪都执行 deploy,就得把它变成可执行文件并加入环境变量路径。
实操分三步:
1. 给脚本加 shebang 并设可执行权限:#!/usr/bin/env php 开头,然后 chmod +x deploy.php;
2. 把它软链或复制到已有的 $PATH 目录(如 ~/bin),或新建一个目录(如 ~/mybin)并追加到 $PATH;
3. 重载 shell 配置(source ~/.bashrc 或 source ~/.zshrc)。
容易踩的坑:
- 脚本开头没写
#!/usr/bin/env php,会导致执行时报 “bad interpreter” - 修改
~/.bashrc后没重载,$PATH不更新 - 用
sudo执行时环境变量丢失,需加-E参数(sudo -E deploy)
容器或 sudo 切换用户后环境变量消失怎么办
根本原因是子进程默认不继承父进程全部环境变量。Docker 容器启动时没加 -e 或 --env-file,或者 sudo 没带 -E,都会导致 getenv() 查不到值。
排查顺序很关键:先进容器或切换用户后直接跑 env | grep DB,确认变量是否真存在;再在 PHP 里 var_dump(getenv('DB_HOST')),排除代码层问题。
多个要点、条件或步骤请使用无序列表呈现:
立即学习“PHP免费学习笔记(深入)”;
- Docker 运行时用
docker run -e DB_HOST=127.0.0.1或docker run --env-file .env -
sudo -u www-data php -r "echo getenv('DB_HOST');"会失败,必须加-E:sudo -E -u www-data ... - PHP-FPM 场景下,变量需在
www.conf里用env[DB_HOST] = $DB_HOST显式透传
最常被忽略的一点:环境变量名拼写、大小写、空格、引号包裹方式,在 .env 文件、Docker 命令、shell export、PHP 读取这四个环节必须完全一致——差一个字符,getenv() 就返回 false,而你可能还在查 PHP 配置。



















