根本原因是shell缓存了php路径,需执行rehash或hash -r刷新;必须将eval "$(phpenv init -)"加入shell配置文件以启用shims和自动钩子,否则phpenv无法正常工作。

phpenv switch 后 php -v 仍显示旧版本
根本原因是 shell 缓存了 php 可执行文件的路径,没有重新扫描 $PATH 中的变更。即使 phpenv switch 8.2 成功执行,which php 或 php -v 仍可能调用旧版本。
必须手动触发 shell 重建命令哈希表:
- 执行
rehash(zsh 默认支持;bash 需确保已启用hash命令) - 或运行
hash -r(bash 兼容写法) - 临时验证可加
-i参数强制忽略缓存:command php -v
注意:仅 rehash 能刷新所有已知命令,hash -d php 只删单个条目,不推荐。
为什么 eval "$(phpenv init -)" 必须写进 .zshrc/.bashrc
这行代码不是“可选配置”,而是 phpenv 正常工作的前提。它做了三件事:注入 phpenv shell 函数、设置 shims 目录到 $PATH、启用自动 rehash 钩子。
立即学习“PHP免费学习笔记(深入)”;
漏掉会导致:
-
phpenv命令本身找不到(PATH 未包含~/.phpenv/bin) - 切换版本后
php命令仍指向系统默认(shims 未生效) - 每次切换都得手动
rehash(缺少 hooks 支持)
确认是否生效:重启终端后运行 type php,输出应为 php is a function,而非 php is /usr/bin/php。
Windows 下 phpEnv(非 phpenv)切换无效的特殊处理
注意区分:Windows 上常见的 phpEnv(带大写 E,图形界面工具)和类 Unix 的 phpenv(全小写,命令行工具)是两个完全不同的项目。前者不修改系统 PATH,只在 GUI 内部生效。
若你在 Windows 上用的是 phpEnv 图形版:
-
php -v在 CMD/PowerShell 中无效,是因为它没改系统环境变量 - 必须手动编辑「系统属性 → 环境变量」,把目标 PHP 版本目录(如
D:\phpEnv\php\php-8.2\)加到Path最前面,并删掉旧版本路径 - 修改后需关闭全部 CMD/PowerShell 窗口再重开,否则
PATH不刷新
这种场景下,rehash 完全不起作用 —— Windows shell 没这个命令。
PHP 进程内 getenv() 读不到 phpenv 切换的版本号
这是常见误解:phpenv 切换的是 shell 中 php 命令的符号链接,不影响已运行的 PHP 进程。Web 服务器(如 Apache/Nginx + PHP-FPM)启动时读取的是其自身进程的环境,与当前 shell 无关。
要让 PHP 脚本感知当前 phpenv 版本,只能:
- 在 CLI 场景下,用
phpenv version-name获取当前激活版本,再通过putenv()注入(仅限当前请求) - 在 Web 场景下,必须通过 Web 服务器配置传递,例如 Nginx 的
fastcgi_param PHP_VERSION $PHP_VERSION;,再在 PHP 中用getenv('PHP_VERSION') - 不要依赖
$_ENV['PATH']解析 PHP 版本,不可靠且易出错
真正容易被忽略的是:FPM 池配置里 env[PATH] 是静态的,不会随 phpenv switch 动态更新 —— 这部分必须单独管理。



















