如何在PHP脚本中运行Terser?依赖版本缺失问题排查
问题
我有一个用于自动化开发到生产流程的PHP脚本,想要用Terser压缩项目里的JS文件。但通过PHP的exec()调用Terser时,返回值为1(表示存在未定义错误)。我做了以下测试:
- 相同的Terser命令在普通Shell中运行正常;
- 执行
exec('ls')能获取PHP脚本所在目录的内容; - Terser命令位于
/usr/local/bin,添加该路径后结果仍相同; - 所有用户对Terser命令及相关文件拥有读取权限;
- JS文件所在目录和目标目录对所有用户开放读写权限。
stderr输出内容如下:
node: /opt/lampp/lib/libstdc++.so.6: version `GLIBCXX_3.4.29' not found (required by /lib/x86_64-linux-gnu/libnode.so.72) node: /opt/lampp/lib/libstdc++.so.6: version `GLIBCXX_3.4.26' not found (required by /lib/x86_64-linux-gnu/libnode.so.72) node: /opt/lampp/lib/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /lib/x86_64-linux-gnu/libnode.so.72) node: /opt/lampp/lib/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /lib/x86_64-linux-gnu/libnode.so.72) node: /opt/lampp/lib/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by /lib/x86_64-linux-gnu/libnode.so.72) node: /opt/lampp/lib/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by /lib/x86_64-linux-gnu/libicui18n.so.70) node: /opt/lampp/lib/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by /lib/x86_64-linux-gnu/libicuuc.so.70)
使用系统为Ubuntu 23.10,请问如何排查该问题并实现从PHP脚本中运行Terser?
解决方案
1. 确认问题根源
PHP通过exec()调用外部命令时,继承了XAMPP(lampp)的环境变量,优先加载了/opt/lampp/lib下的旧版本libstdc++.so.6,而系统中Node.js(Terser依赖Node)需要更高版本的该库。普通Shell环境不会加载XAMPP的库路径,因此命令能正常运行。
2. 临时解决:修改exec调用的环境变量
在PHP的exec()命令中,临时修改LD_LIBRARY_PATH,让系统优先加载系统自带的高版本库,再执行Terser命令。示例代码:
// 先设置系统库路径优先级,再执行Terser压缩命令 $command = 'LD_LIBRARY_PATH=/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu /usr/local/bin/terser input.js -o output.min.js'; exec($command, $output, $return_var); // 检查执行结果 if ($return_var === 0) { echo "JS文件压缩成功"; } else { echo "压缩失败,返回码:$return_var"; print_r($output); }
3. 永久解决:调整XAMPP的库加载优先级
如果不想每次调用都设置环境变量,可以修改XAMPP的启动配置,避免覆盖系统库路径:
- 找到XAMPP的Apache启动脚本(通常为
/opt/lampp/bin/apachectl) - 在脚本开头添加:
unset LD_LIBRARY_PATH,或者修改LD_LIBRARY_PATH,将系统库路径放在/opt/lampp/lib之前
4. 验证系统库版本
先确认系统中是否存在符合要求的libstdc++.so.6版本,执行以下Shell命令:
strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep -E 'GLIBCXX_3.4.20|GLIBCXX_3.4.21|GLIBCXX_3.4.26|GLIBCXX_3.4.29|CXXABI_1.3.8|CXXABI_1.3.9'
如果输出包含所有需要的版本标识,说明系统库满足要求,只需解决路径优先级问题即可。
5. 备选方案:使用PHP的Node.js桥接库
如果上述方法都不适用,可以尝试使用PHP的Node.js桥接库(如v8js),直接在PHP代码中调用Terser的Node.js API,避免通过exec()调用外部命令。
内容的提问来源于stack exchange,提问作者FvEldijk
相关产品推荐
相关产品推荐

