# 编译安装PHP8.2

> wandoubaba / 2023-07-21

以Debian11操作系统为例。

本文目标：在纯净的操作系统上安装PHP8.2环境，同时安装composer和pecl，并通过pecl安装一些常用的扩展，最终实现在环境中运行基于Workerman的项目。

## 安装依赖

```sh
sudo apt-get install -y \
    wget make gcc curl \
    libxml2 libxml2-dev \
    libsqlite3-dev \
    libwebp-dev libonig-dev \
    libsodium-dev pkg-config \
    libssl-dev openssl \
    libgd-dev build-essential \
    zlib1g-dev libpcre3-dev \
    lsb-release autoconf \
    libzip-dev unzip
```

安装`libcurl`

```sh
wget https://curl.se/download/curl-8.2.0.tar.gz
tar zxvf curl-8.2.0.tar.gz
cd curl-8.2.0
./configure --with-openssl
make
make install
```

## 创建安装目录

为了让多个版本的PHP可以共存，我们不准备把PHP安装到默认目录内，而是为每个版本设置一个目录。

```sh
mkdir -p /www/server/php/82/etc
```

## 创建www用户和组

查看www用户是否存在

```sh
id www
```

创建www分组和www用户，并且不允许登录系统

```sh
groupadd www
useradd -g www -s /sbin/nologin www
```

再查看www用户

```sh
id www
```

为www用户创建home目录，composer会用到。

```sh
mkdir /home/www
chown www:www -R /home/www
usermod -d /home/www www
```

## 下载PHP

```sh
wget https://www.php.net/distributions/php-8.2.8.tar.gz
```

## 解压&编译&安装

```sh
tar zxvf php-8.2.8.tar.gz
cd php-8.2.8
./configure \
    --prefix=/www/server/php/82 \
    --with-config-file-path=/www/server/php/82/etc \
    --enable-fpm \
    --with-fpm-user=www \
    --with-fpm-group=www \
    --enable-mysqlnd \
    --with-mysqli=mysqlnd \
    --with-pdo-mysql=mysqlnd \
    --with-freetype \
    --with-jpeg \
    --with-zlib \
    --enable-xml \
    --disable-rpath \
    --enable-bcmath \
    --enable-shmop \
    --enable-sysvsem \
    --with-curl \
    --enable-mbregex \
    --enable-mbstring \
    --enable-intl \
    --enable-ftp \
    --enable-gd \
    --with-openssl \
    --with-mhash \
    --enable-pcntl \
    --enable-sockets \
    --enable-soap \
    --with-gettext \
    --disable-fileinfo \
    --enable-opcache \
    --with-sodium=/usr/local/libsodium \
    --with-webp
make
sudo make install
```

## 创建全局命令

```sh
ln -s /www/server/php/82/bin/php /usr/local/bin/php
ln -s /www/server/php/82/bin/phpize /usr/local/bin/phpize
```

## 创建php.ini

在PHP的源码目录下有`php.ini-development`和`php.ini-production`两个文件，分别表示“开发环境配置”和“生产环境配置”，这里我们直接使用生产环境的。

```sh
cp php.ini-production /www/server/php/82/etc/php.ini
```

## 安装composer

```sh
cd /www/server/php/82/bin
php -r "copy('https://install.phpcomposer.com/installer', 'composer-setup.php');"
php composer-setup.php
ln -s /www/server/php/82/bin/composer.phar /usr/local/bin/composer
composer selfupdate
composer --version
```

把composer源改成国内镜像

```sh
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
```

## 安装pecl

pecl是可以方便为PHP安装扩展的工具。

```sh
cd /www/server/php/82/bin
wget http://pear.php.net/go-pear.phar
php go-pear.phar
ln -s /www/server/php/82/bin/pecl /usr/local/bin/pecl
```

## 安装扩展

- event扩展

event扩展可以使基于Workerman的项目发挥更高的性能。

注意提示：Include libevent OpenSSL support [yes] : 时输入no回车，其它直接敲回车就行。

```sh
apt-get install libevent-dev -y
pecl install event
```

安装成功后，命令行会提示编译后的库文件所在的位置，如`/www/server/php/82/lib/php/extensions/no-debug-non-zts-20220829/event.so`。

在`php.ini`文件的最后添加下面的内容：

```ini
[event]
extension="/www/server/php/82/lib/php/extensions/no-debug-non-zts-20220829/event.so"
```

再执行`php -m`命令后会看到`event`扩展出现在了已安装的扩展列表中，说明扩展安装成功。

- zip扩展

```sh
pecl install zip
```

在`php.ini`文件的最后添加：

```ini
[zip]
extension="/www/server/php/82/lib/php/extensions/no-debug-non-zts-20220829/zip.so"
```

- redis扩展

```sh
pecl install redis
```

在`php.ini`文件的最后添加：

```ini
[redis]
extension="/www/server/php/82/lib/php/extensions/no-debug-non-zts-20220829/redis.so"
```

- swoole扩展

```sh
pecl install swoole
```

在`php.ini`文件的最后添加：

```ini
[swoole]
extension="/www/server/php/82/lib/php/extensions/no-debug-non-zts-20220829/swoole.so"
```

- protobuf扩展

如果项目中需要使用到gRPC服务端或客户端，就要安装protobuf扩展

```sh
pecl install protobuf
```

在`php.ini`文件的最后添加：

```ini
[protobuf]
extension="/www/server/php/82/lib/php/extensions/no-debug-non-zts-20220829/protobuf.so"
```

- xlswriter扩展

如果项目中需要读或写excel文件，可以尝试一下这个扩展，它的最大特点的就解析速度，无论读还是写（但是并不具备phpoffice/phpspreadsheet的所有功能）。

```sh
pecl install xlswriter
```

在`php.ini`文件的最后添加：

```ini
[xlswriter]
extension="/www/server/php/82/lib/php/extensions/no-debug-non-zts-20220829/xlswriter.so"
```

- pdo_pgsql扩展

如果项目中需要使用postgresql数据库，就需要安装这个扩展。

先安装pg数据库的驱动库libpg：

```sh
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt-get update
sudo apt-get -y install libpq-dev
```

然后进入PHP源代码目录中的`ext/pdo_pgsql`目录下

```sh
## 注意要把下面的path/to换成实际路径
cd path/to/php-8.2.8/ext/pdo_pgsql
phpize
./configure --with-php-config=/www/server/php/82/bin/php-config
make
make install
```

在`php.ini`文件的最后添加：

```ini
[pdo_pgsql]
extension="/www/server/php/82/lib/php/extensions/no-debug-non-zts-20220829/pdo_pgsql.so"
```

- fileinfo扩展

fileinfo通过在文件的给定位置查找特定的魔术字节序列,来获取文件的MIME信息。laravel框架依赖这个扩展。

进入PHP源代码目录中的`ext/fileinfo`目录下

```sh
## 注意要把下面的path/to换成实际路径
cd path/to/php-8.2.8/ext/fileinfo
phpize
./configure --with-php-config=/www/server/php/82/bin/php-config
make
make install
```

在`php.ini`文件的最后添加：

```ini
[fileinfo]
extension="/www/server/php/82/lib/php/extensions/no-debug-non-zts-20220829/fileinfo.so"
```

## 测试

独立的php-cli环境已经安装完成了，下面我们可以用简单的HTTP服务框架`webman`测试一下。

```sh
mkdir /www/wwwroot
cd /www/wwwroot
composer create-project workerman/webman
cd webman
php start.php start
```

一切顺利的话，应该可以在命令行中看到已经启动了名为`webman`的服务进程，默认监听端口`8787`

```sh
Workerman[start.php] start in DEBUG mode
------------------------------------------- WORKERMAN -------------------------------------------
Workerman version:4.1.11          PHP version:8.2.8           Event-Loop:\Workerman\Events\Event
-------------------------------------------- WORKERS --------------------------------------------
proto   user            worker          listen                 processes    status
tcp     root            webman          http://0.0.0.0:8787    16            [OK]
tcp     root            monitor         none                   1             [OK]
-------------------------------------------------------------------------------------------------
Press Ctrl+C to stop. Start success.
```

这个时候使用浏览器访问`http://ip:8787`就可以看到webman框架的欢迎页了。

## 启用php-fpm

为了与nginx整合以支持类似laravel或tp这样的fpm框架，我们还需要启动php-fpm服务。

```sh
ln -s /www/server/php/82/sbin/php-fpm /usr/local/bin/php-fpm
cd /www/server/php/82/etc/php-fpm.d
cp www.conf.default www.conf
php-fpm
```

要实现多版本PHP环境共存，主要是解决不同版本的php-fpm服务监听端口冲突的问题，我们可以做个约定规则，就是让各个版本的php-fpm都监听`90xx`端口，比如我们现在安装的是8.2版本，那就让它的php-fpm监听`9082`端口。

修改`www.conf`文件，找到`listen = 127.0.0.1:9000`一行，把它改为`listen = 127.0.0.1:9082`，保存退出即可。

下面要把php-fpm注册为系统服务。

```sh
touch /etc/systemd/system/php-fpm.service
vim /etc/systemd/system/php-fpm.service
```

文件内容：

```ini
[Unit]
Description=The PHP 8.2 FastCGI Process Manager
After=network.target

[Service]
Type=simple
PIDFile=/run/php-fpm.pid
ExecStart=/www/server/php/82/sbin/php-fpm --nodaemonize --fpm-config /www/server/php/82/etc/php-fpm.conf
ExecReload=/bin/kill -USR2 MAINPID
ExecStop=/bin/kill −SIGINT MAINPID
Restart=always

[Install]
WantedBy=multi-user.target
```

保存退出后执行下面的命令：

```sh
sudo systemctl daemon-reload
sudo systemctl enable php-fpm
```

服务控制命令：

```sh
sudo systemctl start php-fpm
sudo systemctl restart php-fpm
sudo systemctl stop php-fpm
sudo systemctl reload php-fpm
sudo systemctl status php-fpm
```