构建基于RHEL9系列(CentOS9,AlmaLinux9,RockyLinux9等)的支持63个常见模块的PHP8.1.20的RPM包
本文适用:rhel9系列,或同类系统(CentOS9,AlmaLinux9,RockyLinux9等)
文档形成时期:2023年
因系统版本不同,构建部署应略有差异,但本文未做细分,对稍有经验者应不存在明显障碍。
因软件世界之复杂和个人能力之限,难免疏漏和错误,欢迎指正。
文章目录
- 背景
- 环境准备
- 依赖包和必要文件准备
- php-8.1.20-el9.spec内容
- 构建
- 目标服务器安装
- 支持的模块
背景
不同时期因各种原因经常产生部署LNMP环境的需求,某些场景下需要自定义软件,比如参数、模块、安装路径,或多个版本共存,不能采用Docker等容器环境,采用自主构建RPM包便成了比较快捷的方式之一。
环境准备
yum install rpmdevtools
#创建目录
rpmdev-setuptree
#或手动创建目录:
mkdir rpmbuild-php-8.1.20; cd rpmbuild-php-8.1.20
mkdir -p ./{BUILD,RPMS,SOURCES,SPECS,SRPMS}
依赖包和必要文件准备
#安装扩展源并启用crb(如果不启用,很多依赖得手动装)
dnf install epel-release
dnf config-manager --set-enabled crb
#通过dnf安装依赖
dnf -y install wget libxml2 libxml2-devel sqlite-devel bzip2-devel libcurl-devel libffi-devel libpng-devel libwebp-devel libjpeg-devel freetype-devel oniguruma oniguruma-devel libzip libzip-devel unixODBC unixODBC-devel freetds freetds-devel libtool-ltdl libtool-ltdl-devel gmp-devel libicu-devel openldap openldap-devel libpq libpq-devel aspell aspell-devel libtidy libtidy-devel libxslt libxslt-devel readline readline-devel libsodium libsodium-devel libjpeg-turbo-utils libXpm-devel systemd-devel
openssl openssl-devel
cp -frp /usr/lib64/libldap* /usr/lib/
目录rpmbuild/SOURCES/下面的文件:
opcache.so php-8.1.20.tar.gz php-command.ini php-fpm.conf php.ini redis.so www.conf

说明:
- PHP配置建议参考生产环境的常用配置,准备一个比较通用的;
- opcache.so和redis.so是同环境下编译好的模块文件,这样可省略在RPM包构建过程中执行编译;
php-8.1.20-el9.spec内容
Name: php
Summary: PHP: Hypertext Preprocessor
Group: Development/Languages
Version: 8.1.20
Release: custom%{?dist}
Source: php-8.1.20.tar.gz
#Icon: php.gif
URL: http://www.php.net/
Packager: PHP Group <group@php.net>
License: GPL%define _prefix /opt/php81
Prefix: %{_prefix}%description
Copyright: The PHP license (see "LICENSE" file included in distribution)
PHP is an HTML-embedded scripting language. Much of its syntax is
borrowed from C, Java and Perl with a couple of unique PHP-specific
features thrown in. The goal of the language is to allow web
developers to write dynamically generated pages quickly.%prep%setup -q%build
set -x
# ./buildconf
./configure --prefix=%{_prefix} --sysconfdir=%{_prefix}/etc --with-config-file-path=%{_prefix}/etc --with-openssl --with-zlib --with-bz2 --with-curl --enable-bcmath --enable-gd --with-webp --with-jpeg --with-xpm --with-freetype --with-mhash --enable-mbstring --with-imap-ssl --enable-exif --with-ffi --with-zip --enable-sockets --with-pcre-jit --enable-fpm --with-pdo-mysql --enable-pcntl --with-gettext --with-gmp --with-fpm-user=www --with-fpm-group=www --with-fpm-systemd --enable-sysvmsg --enable-sysvsem --enable-sysvshm --with-mysqli --enable-mysqlnd --with-pdo-dblib --with-unixODBC --with-pdo-odbc=unixODBC,/usr/ --with-pgsql --with-pdo-pgsql --enable-ftp --enable-dba --enable-calendar --enable-intl --with-ldap --with-pspell --enable-shmop --enable-soap --with-tidy --with-xsl --with-readline --with-sodiumsed -ri "/^EXTRA_LIBS/s/(.*)/\1 -llber/" Makefilemake %{?_smp_mflags}#
# Installation section
#%install
[ %{buildroot} != "/" ] && rm -rf %{buildroot}
# %__make install DESTDIR="%{buildroot}" # 经实践,该参数不行,要使用下面的INSTALL_ROOT。
make INSTALL_ROOT="%{buildroot}" install%__install -c -d -m 755 "%{buildroot}/opt"
%__install -c -d -m 755 "%{buildroot}%{_prefix}/etc"
%__install -c -d -m 755 "%{buildroot}%{_prefix}/etc/php-fpm.d"
%__install -c -d -m 755 "%{buildroot}/usr/lib/systemd/system"
%__install -c -d -m 755 "%{buildroot}%{_prefix}/lib/php/extensions/no-debug-non-zts-20210902"
cp -f %_sourcedir/{php-command.ini,php.ini,php-fpm.conf} "%{buildroot}%{_prefix}/etc/"
cp -f %_sourcedir/www.conf "%{buildroot}%{_prefix}/etc/php-fpm.d/"
cp -f %_builddir/%{name}-%{version}/sapi/fpm/php-fpm.service "%{buildroot}/usr/lib/systemd/system/php-fpm.service"
cp -f %_sourcedir/redis.so "%{buildroot}%{_prefix}/lib/php/extensions/no-debug-non-zts-20210902/"
cp -f %_sourcedir/opcache.so "%{buildroot}%{_prefix}/lib/php/extensions/no-debug-non-zts-20210902/"#
# Clean section
#%clean
[ %{buildroot} != "/" ] && rm -rf "%{buildroot}"%files
%defattr(-,root,root)
%{_prefix}
# 不在prefix路径下的文件需要单独指定
/usr/lib/systemd/system/php-fpm.service%post
if [ $1 == 1 ];thengroupadd www -g 319 2> /dev/nulluseradd -s /sbin/nologin -M www -u 319 -g 319 2> /dev/nullmkdir /home/www 2> /dev/nullchown www:www /home/www 2> /dev/nullsystemctl daemon-reloadsystemctl enable php-fpm
fi%preun
if [ "$1" = 0 ]
thensystemctl disable php-fpmsystemctl stop php-fpm# userdel wwwcp %{_prefix}/etc/php.ini /opt/php.ini.rpmsave-`date +"%%Y%%m%%d-%%H%%M%%S"`cp %{_prefix}/etc/php-command.ini /opt/php-command.ini.rpmsave-`date +"%%Y%%m%%d-%%H%%M%%S"`cp %{_prefix}/etc/php-fpm.conf /opt/php-fpm.conf.rpmsave-`date +"%%Y%%m%%d-%%H%%M%%S"`cp %{_prefix}/etc/php-fpm.d/www.conf /opt/www.conf.rpmsave-`date +"%%Y%%m%%d-%%H%%M%%S"`
fi%postun
if [ "$1" = 0 ]
thensystemctl disable php-fpmrm -f /usr/lib/systemd/system/php-fpm.servicerm -rf /opt/php81echo "%{name}-%{version}-%{release}已经卸载."
fi%changelog
* Mon Dec 11 2023 N
- For the first time, Custom made PHP8.1.20 in AlmaLinux9.2.
和RHEL8的不同的是:
date +“%Y%m%d-%H%M%S”
改为了:
date +“%%Y%%m%%d-%%H%%M%%S”
查看make参数:
rpm --eval %{?_smp_mflags}
可以看到是根据核线程数量来编译的。
构建
QA_RPATHS=$(( 0x0001|0x0002 )) rpmbuild -ba --define "_topdir `pwd`" --nodebuginfo SPECS/php-8.1.20-el9.spec
构建成功的包如下:
php-8.1.20-custom.el9.x86_64.rpm
目标服务器安装
#仍要安装依赖的扩展源,需启用crb
dnf install epel-release
dnf config-manager --set-enabled crb
dnf localinstall php-8.1.20-custom.el9.x86_64.rpm
支持的模块
/opt/php81/bin/php -m
[PHP Modules]
bcmath
bz2
calendar
Core
ctype
curl
date
dba
dom
exif
FFI
fileinfo
filter
ftp
gd
gettext
gmp
hash
iconv
intl
json
ldap
libxml
mbstring
mysqli
mysqlnd
odbc
openssl
pcntl
pcre
PDO
pdo_dblib
pdo_mysql
PDO_ODBC
pdo_pgsql
pdo_sqlite
pgsql
Phar
posix
pspell
readline
redis
Reflection
session
shmop
SimpleXML
soap
sockets
sodium
SPL
sqlite3
standard
sysvmsg
sysvsem
sysvshm
tidy
tokenizer
xml
xmlreader
xmlwriter
xsl
zip
zlib[Zend Modules]
相关文章:
构建基于RHEL9系列(CentOS9,AlmaLinux9,RockyLinux9等)的支持63个常见模块的PHP8.1.20的RPM包
本文适用:rhel9系列,或同类系统(CentOS9,AlmaLinux9,RockyLinux9等) 文档形成时期:2023年 因系统版本不同,构建部署应略有差异,但本文未做细分,对稍有经验者应不存在明显障碍。 因软件世界之复杂和个人能力…...
你知道什么是Java中的类型强转吗?
强制类型转换 强转存在与父转子的时候,子转父不需要进行强转,如 Object o "hello"; //String类是Object类的子类,无需进行强转类型强转分为两种情况: Ⅰ、向下转型:将父类对象引用转换为子类对象引用&am…...
【2023】ArrayList和LinkedList详解介绍对比
一、ArrayList 1、概述 ArrayList是实现了List接口的动态数组,所谓动态数组就是他的大小是可变的。实现了所有可选列表操作,并允许包括Null在内的所有元素。除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。 …...
【软件工程】基于领域建模的产品与技术方案设计(领域驱动设计DDD)
文章目录 1、领域建模2、产品方案、技术方案3、领域驱动设计DDD 1、领域建模 领域模型(domain model) 是对领域内的概念类或现实世界中对象的可视化表示。领域模型也成为概念模型、领域对象模型和分析对象模型。域模型是一种概念模型,也叫问题域模型。它表述的是某…...
跨境电商账号频繁?你的IP可能“不干净”了
疫情促进了跨境电商行业的加速发展,许多卖家也抓住了这波流量红利,跨境电商月入数万,数十万甚至数百万的造福神话也不断在上演,但由于国内外电商运营模式不同,多店运营、用户数据收集、刷单等行为都受到了国外平台的严…...
Docker数据卷与拦截与目录拦截
目录 高级容器挂载技术深度解析引言数据卷挂载原理解析应用场景使用介绍 目录挂载原理解析应用场景使用介绍 总结 高级容器挂载技术深度解析 引言 容器技术的快速发展使得容器挂载技术变得愈发重要。在容器化应用中,数据卷挂载和目录挂载是两种常见的挂载方式&…...
Python 元类 metaclass 详解
元类(metaclass)是 Python 中一个高级且相对较少使用的概念。元类可以被视为类的类,它控制类的创建过程。 一、基本概念 在 Python 中,一切皆对象。为了避免混淆,我们约定两个术语: 类实例:当…...
HCIA基础知识
IP地址、静态路由、动态路由、交换机 OSPF RIP DHCP VLAN ACL NAT OSI TCP/IP UDP TCP 三次握手,四次挥手,报头 什么是网络? 由网络连接设备通过传输介质将网络终端设备连接起来,进行资源共享、信息传递的平台。 OSI七…...
翻译: Streamlit从入门到精通 部署一个机器学习应用程序 四
Streamlit从入门到精通 系列: 翻译: Streamlit从入门到精通 基础控件 一翻译: Streamlit从入门到精通 显示图表Graphs 地图Map 主题Themes 二翻译: Streamlit从入门到精通 构建一个机器学习应用程序 三 1. 5. 如何部署一个Streamlit应用 部署是将应用程序从开发…...
AI时代Python量化交易实战:ChatGPT引领新时代
文章目录 《AI时代Python量化交易实战:ChatGPT让量化交易插上翅膀》关键点内容简介作者简介购买链接 《AI时代架构师修炼之道:ChatGPT让架构师插上翅膀》关键点内容简介作者简介 赠书活动 《AI时代Python量化交易实战:ChatGPT让量化交易插上翅…...
国科大软件安全原理期末复习笔记
1 软件安全总论 1.软件的三大特性:复杂性、互连性、可扩展性; 2.基本概念:缺陷、漏洞、风险 缺陷(bug):软件在设计和实现上的错误;漏洞(vulnerability):漏洞…...
人工智能软件测试2024年主要趋势
人工智能软件测试领域在未来可能面临多个发展趋势,其中一些趋势可能会对测试方法、工具和流程产生深远的影响。以下是塑造人工智能软件测试未来的主要趋势: 自动化和自动学习测试:随着人工智能的发展,测试自动化将变得更加智能和自…...
【JAVA】Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式
🍎个人博客:个人主页 🏆个人专栏:JAVA ⛳️ 功不唐捐,玉汝于成 目录 前言 正文 懒汉式(Lazy Initialization): 双重检查锁定(Double-Checked Locking)…...
常见的反爬虫风控 | 验证码风控
一.前言 在当今信息技术迅速发展的背景下,网站和在线服务面临着日益增长的自动化访问威胁,这些大多来自于各类爬虫程序。这种大量的自动化访问不仅对网站的正常运行构成压力,还可能导致敏感数据的泄露,甚至被用于不正当竞争和恶意…...
ClickHouse(21)ClickHouse集成Kafka表引擎详细解析
文章目录 Kafka表集成引擎配置Kerberos 支持 虚拟列 资料分享参考文章 Kafka表集成引擎 此引擎与Apache Kafka结合使用。 Kafka 特性: 发布或者订阅数据流。容错存储机制。处理流数据。 老版Kafka集成表引擎参数格式: Kafka(kafka_broker_list, kaf…...
JSP-概念
一、引子 很多读者可能听过JSP,并且知道这是一门过时的技术了。在Spring,SpringBoot已经成为主流的今天,笔者为什么还要介绍JSP的相关内容呢?笔者常常提到一个概念:理解一门技术,要理解这个技术为什么产生…...
sqlite插入语句id自增列问题
sqlite给主键id设置AUTOINCREMENT自增在插入数据的时候报错table has x columns but x-1 values were supplied 为什么自增列要显示不提供,sqlite需要提供自增列table ResTools has 7 columns but 6 values were supplied SQL Statement:insert into ResTools values(管理系统w…...
C#,字符串匹配(模式搜索)AC(Aho Corasick)算法的源代码
Aho-Corasick算法简称AC算法,也称为AC自动机(Aho-Corasick)算法,1975年产生于贝尔实验室(The Bell Labs),是一种用于解决多模式字符串匹配的经典算法之一。 the Bell Lab 本文的运行效果: AC算法以模式树…...
【网络取证篇】Windows终端无法使用ping命令解决方法
【网络取证篇】Windows终端无法使用ping命令解决方法 以Ping命令为例,最近遇到ping命令无法使用的情况,很多情况都是操作系统"环境变量"被改变或没有正确配置导致—【蘇小沐】 目录 1、实验环境(一)无法ping命令 &a…...
electron+vue网页直接播放RTSP视频流?
目前大部分摄像头都支持RTSP协议,但是在浏览器限制,最新版的浏览器都不能直接播放RTSP协议,Electron 桌面应用是基于 Chromium 内核的,所以也不能直接播放RTSP,但是我们又有这个需求怎么办呢? 市场上的方案…...
Unity游戏开发实战:用三阶贝塞尔曲线为你的角色设计一条丝滑的移动路径(附完整C#脚本)
Unity游戏开发实战:三阶贝塞尔曲线打造丝滑角色移动路径 想象一下,你的游戏角色需要完成一个优雅的空中翻转动作,或者赛车需要在弯道实现完美漂移轨迹。这些令人惊叹的运动效果背后,往往隐藏着一条看不见的数学曲线——贝塞尔曲线…...
大脑极简原理:比冯·诺依曼架构还简单的电磁路由网络 ——为什么意识和智能会从“对称判断”里自然涌现
前言:被复杂化的真相——大脑其实简单到爆我们从小被灌输一个观念:大脑是宇宙中最复杂的系统,860亿神经元、百万亿突触、无数神经递质,像一台精密到无法拆解的超级计算机。神经科学论文越写越长,模型越来越复杂&#x…...
解密革命性构建工具:PoeCharm如何突破传统限制实现高效角色规划
解密革命性构建工具:PoeCharm如何突破传统限制实现高效角色规划 【免费下载链接】PoeCharm Path of Building Chinese version 项目地址: https://gitcode.com/gh_mirrors/po/PoeCharm 在流放之路的复杂游戏生态中,角色构建往往成为玩家面临的最大…...
手把手教你用EFR32BG22实现BLE串口透传(附GATT配置全流程)
EFR32BG22低功耗蓝牙串口透传开发实战指南 在物联网终端设备开发中,蓝牙串口透传是最基础也最实用的功能之一。本文将带您深入EFR32BG22芯片的蓝牙开发世界,从零开始构建一个高效的BLE串口透传服务。不同于简单的代码搬运,我们将重点关注GATT…...
Python 3.15 JIT不是“可选优化”——而是CPython官方首次强制嵌入的LLVM后端(2024 Q3起新项目默认启用)
第一章:Python 3.15 JIT 的历史定位与架构革命Python 3.15 标志着 CPython 运行时的一次范式跃迁——它首次将生产就绪的、默认启用的即时编译(JIT)引擎深度集成至解释器核心,而非作为外部补丁或实验性分支存在。这一设计终结了自…...
从随机采样到精准决策:蒙特卡罗方法在复杂系统建模中的实践
1. 蒙特卡罗方法:用随机性破解复杂世界的密码 想象你是一位古代数学家,手里只有一把沙子和一块画着方格的石板。现在要计算一个不规则形状的湖泊面积,你会怎么做?最原始的方法可能是把沙子均匀撒在石板上,然后数出落在…...
用Python代码和蒙特卡洛方法,手把手教你估算强化学习中的状态价值(附完整代码)
用Python实现蒙特卡洛方法估算强化学习状态价值的实战指南 马尔可夫决策过程(MDP)是强化学习的数学基础框架,而状态价值函数则是评估策略优劣的核心指标。许多初学者在理解抽象的状态价值概念时会遇到困难——这些数字究竟是如何从实际交互中…...
冒险岛V128单机版服务端魔改指南:从基础搭建到自定义任务/装备修改
冒险岛V128单机版深度定制指南:从零构建个性化游戏世界 在数字娱乐的黄金时代,怀旧游戏焕发新生已成为一种文化现象。作为横版卷轴网游的经典之作,冒险岛凭借其独特的艺术风格和社交属性,至今仍拥有大量忠实玩家。而单机版的出现&…...
OpenClaw浏览器自动化:ollama-QwQ-32B驱动的研究资料收集系统
OpenClaw浏览器自动化:ollama-QwQ-32B驱动的研究资料收集系统 1. 为什么需要自动化研究资料收集 作为一名经常需要查阅大量文献的技术写作者,我长期被资料收集的效率问题困扰。传统工作流程中,我需要手动在Google Scholar、arXiv、知乎等平…...
AT32F435_437_USB_MSC_SDIO:实现高效SD卡U盘功能的开发指南
1. 从零开始:AT32F435/437的USB MSC功能初探 第一次接触AT32F435/437的USB大容量存储设备(MSC)功能时,我完全被它的实用性惊艳到了。想象一下,你的嵌入式设备突然变身成电脑上的U盘,可以直接拖拽文件读写SD卡,这对数据…...
