编译安装PHP的Redis拓展

前言

因PHP项目需要用到Redis,但PHP原生并不支持Redis,需要通过安装拓展来支持这一特性。

环境

以下是本篇博文所使用的环境

  • 系统:Debian9
  • PHP版本:7.2
  • PHP安装方式:APT在线源安装
  • 运行方式:nginx & PHP-FPM

通过PECL安装

当然也可以通过pecl安装,安装命令如下

> pecl install redis

执行完毕之后按照提示修改配置文件加载redis.so即可

不过因为服务器在国外的原因,使用这个方法安装失败率极高或非常缓慢(这东西好像还没有国内的镜像站?)。

开始第一步,下载源代码

直接从github克隆phpredis这个项目的源代码即可。若太慢可以使用gitee中转一下或者使用git代理

> git clone https://github.com/phpredis/phpredis

随后cd到该项目的目录下

配置PHP版本信息

在phpredis项目根目录下执行命令phpize

若没有这个命令,安装php{版本号}-dev即可,如

> apt install php7.2-dev

命令执行完毕后提示如下:(我使用的是PHP7.2)

Configuring for:
PHP Api Version:         20170718
Zend Module Api No:      20170718
Zend Extension Api No:   320170718

这时候直接使用make会提示找不到目标,因为我们还没配置编译信息,没有生成该项目的Makefile

配置编译信息

使用该项目下的configure程序来进行配置,直接执行./configure即可,不需要提供其他参数

注:若你是使用自行编译安装或直接下载PHP的二进制包,可能需要指定./configure的命令行选项--with-php-config=,该选项的值为php-config的完整路径

编译完成后显示如下

----------------------------------------------------------------------
Libraries have been installed in:
   /home/xiaotao/phpredis/modules
   (也就是说,编译后的文件在这个项目目录下的modules中)
...其他说明省略...
----------------------------------------------------------------------

Build complete.
Don't forget to run 'make test'.

现在modules目录下的redis.so便是我们需要的拓展文件了

添加文件到拓展目录

复制modules目录下的redis.so文件到/usr/lib/php/20170718/
通过包管理器安装的PHP拓展库默认在/usr/lib/php/[PHP API 版本号]
PHP API版本号可以通过刚刚生成PHP配置的步骤时,使用phpize命令会输出PHP Api Version

若不清楚这个目录,使用php的phpinfo()函数可以找到拓展文件的目录,在Linux下我们直接用管道配合grep即可快速找到这个目录,使用如下命令

注:php -iecho "<?php phpinfo() ?>" | php 在控制台中输出内容一致

> php -i | grep extension_dir
# 对于php-fpm
> php-fpm7.2 -i | grep extension_dir

输出

extension_dir => /usr/lib/php/20170718 => /usr/lib/php/20170718

让PHP加载这个拓展模块

网上很多教程都是直接编辑php.ini添加一行extension=redis.so,实际上这种做法不太妥当
因为redis拓展依赖json拓展,使用这种方法会导致json拓展加载之前加载redis,从而导致redis拓展加载失败,之前被这个问题坑了我一整天

正确的姿势

cd到php.ini同目录下的conf.d目录(如:/etc/php/7.2/fpm/conf.d),ls一下观察这个目录的文件

[xiaotao@debian:/etc/php/7.2/fpm/conf.d]$ ls
10-mysqlnd.ini   20-dom.ini       20-intl.ini       20-posix.ini      20-sysvmsg.ini    20-xmlwriter.ini
10-opcache.ini   20-exif.ini      20-json.ini       20-readline.ini   20-sysvsem.ini    20-xsl.ini
10-pdo.ini       20-fileinfo.ini  20-mbstring.ini   20-shmop.ini      20-sysvshm.ini    20-zip.ini
15-xml.ini       20-ftp.ini       20-mysqli.ini     20-simplexml.ini  20-tokenizer.ini
20-calendar.ini  20-gettext.ini   20-pdo_mysql.ini  20-soap.ini       20-wddx.ini
20-ctype.ini     20-iconv.ini     20-phar.ini       20-sockets.ini    20-xmlreader.ini

根据文件名大概都能猜到前面的两个数字应该是优先级
所以在创建一个目录下创建一个文件25-redis.ini,文件内容如下

extension=redis.so

redis.so可替换为该文件的绝对路径

到这里,配置结束

检查是否成功

> php -i | grep redis
# 对于php-fpm
> php-fpm7.2 -i | grep redis

出现大量相关输出即表示成功,若失败,可使用php -tphp-fpm7.2 -t查看原因

或使用

echo "<?php var_dump(new Redis()); ?>" | php

若输出

object(Redis)#1 (0) {
}

而没有报错 也说明配置成功

注意事项

php-fpm与php的配置是互相独立的
两者的默认配置文件目录如下

  • php /etc/php/{版本号}/cli
  • php-fpm /etc/php/{版本号}/fpm