需先确认phpEnv中PHP版本及线程安全模式:执行phpenv which php、php -v、php -i | grep -E "(Thread Safety|Architecture)",明确TS/NTS与架构;再下载匹配的ZendGuardLoader.so并放入对应extension_dir,修改该版本php.ini启用。

确认phpEnv中PHP版本与线程安全模式
phpEnv 是多版本 PHP 环境管理工具,但它的每个 PHP 实例都是独立编译的,ZendGuardLoader 必须严格匹配 PHP 主版本(5.3–5.6)、小版本号(如 5.4.45)、架构(x86_64/i386)和线程安全标识(TS/NTS)。不匹配会导致 PHP Warning: PHP Startup: Unable to load dynamic library 或直接 segfault。
执行以下命令确认关键信息:
phpenv which php php -v php -i | grep -E "(Thread Safety|Build Date|Architecture)"
注意输出中 Thread Safety => enabled 表示 TS,disabled 表示 NTS;Architecture => x86_64 决定你要下 64 位 loader;Build Date 可辅助判断 ABI 兼容性(如 glibc23)。
- phpEnv 默认安装的 PHP 多为 NTS 模式(尤其通过
phpenv install编译的),但部分预编译包可能是 TS —— 不能凭经验猜,必须查 - PHP 5.6.40 和 5.6.41 虽同属 5.6,但 ZendGuardLoader.so 文件不可互换
- phpEnv 不提供一键扩展市场,所有 loader 安装都需手动完成
下载并部署对应版本的 ZendGuardLoader.so
官方源已下线,可靠镜像路径如下(以 PHP 5.4 NTS x86_64 为例):
立即学习“PHP免费学习笔记(深入)”;
wget https://downloads.zend.com/guard/6.0.0/ZendGuardLoader-php-5.4-linux-glibc23-x86_64.tar.gz tar -xzf ZendGuardLoader-php-5.4-linux-glibc23-x86_64.tar.gz
关键不是解压到哪,而是把 ZendGuardLoader.so 放进当前 phpEnv 版本的 extension_dir 目录:
php -r "echo ini_get('extension_dir');"
输出类似 /home/username/.phpenv/versions/5.4.45/lib/php/extensions/no-debug-non-zts-20100525,这就是你要复制的目标路径。
- 不要复制到系统级目录(如
/usr/lib/php/modules),phpEnv 的 PHP 进程不会读那里 - 若
extension_dir下有多个子目录(如含 zts 字样),只选与你 PHP 的 TS/NTS 状态一致的那个 - 文件权限需为
644,且属主为运行 PHP 的用户(如 www-data 或你的登录用户)
修改对应 PHP 版本的 php.ini
phpEnv 每个版本有独立 php.ini,路径通常为:~/.phpenv/versions/<version>/etc/php.ini。别改全局或 Apache 的 php.ini。
在该文件末尾添加(注意路径必须与上一步 extension_dir 输出完全一致):
zend_extension=/home/username/.phpenv/versions/5.4.45/lib/php/extensions/no-debug-non-zts-20100525/ZendGuardLoader.so zend_loader.enable=1 zend_loader.disable_licensing=1
zend_loader.disable_licensing=1 是必须项,否则加载加密脚本时会因无许可证报错退出。
- 用
zend_extension,不是extension—— 后者仅用于普通扩展,loader 是 Zend 引擎级模块 - 路径中不能有 ~ 符号,必须写绝对路径
- 如果 php.ini 中已有其他
zend_extension行(如 opcache),确保新行不被注释、不重复
验证是否生效及常见失败信号
执行 php -m | grep zend,应看到 zendguardloader;再运行 php -i | grep -A5 "Zend Guard",应显示版本与启用状态。
若仍不生效,最常踩的坑是:
-
php -v显示的版本 ≠ 当前 CLI 使用的 phpEnv 版本(忘记执行phpenv shell 5.4.45) - Web 服务器(如 Nginx + PHP-FPM)用的是另一个 phpEnv 版本,需单独为其配置
php.ini - PHP-FPM pool 配置中显式设置了
php_admin_value[extension_dir],覆盖了 php.ini 中的路径 - loader 加载后,
phpinfo()页面里看不到 “Zend Guard Loader” 段落,但php -m有 —— 这说明 CLI 生效,但 FPM 或 Apache 没重载配置
真正麻烦的不是安装步骤,而是 phpEnv 多版本间 loader 的隔离性 —— 一个版本装好了,不代表其他版本能用,也不能共用同一个 .so 文件路径。



















