CentOS下多版本PHP配置 - 图1

一、前言

为了应对不同的web程序运行,经常会用到多版本PHP配置以方便灵活切换。
这里采用Nginx+多版本PHP的方式运行,PHP安装方式为编译安装。

二、前期准备

  • PHP下载
    下载地址:www.php.net或museum.php.net
    版本选择:PHP5.2/5.3/5.4/5.5/5.6/7.2根据需要选择,我这里使用PHP5.6和7.2版本演示。

  • 依赖安装
    yum install -y make cmake gcc gcc-c++ autoconf automake libpng-devel libjpeg-devel zlib libxml2-devel ncurses-devel bison \ libtool-ltdl-devel libiconv libmcrypt mhash mcrypt pcre-devel openssl-devel freetype-devel libcurl-devel

  • PHP安装
    使用./configure —help查看编译支持的选项。如果写了不支持的选项,如php7里不支持—with-mysql=mysqlnd会提示:
    configure: WARNING: unrecognized options: --with-mysql

  1. #编译参数
  2. ./configure --prefix=/usr/local/php --with-config-file-scan-dir=/usr/local/php/etc/ --enable-inline-optimization --enable-opcache --enable-session --enable-fpm --with-mysql=mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-pdo-sqlite --with-sqlite3 --with-gettext --enable-mbregex --enable-mbstring --enable-xml --with-iconv --with-mcrypt --with-mhash --with-openssl --enable-bcmath --enable-soap --with-xmlrpc --with-libxml-dir --enable-pcntl --enable-shmop --enable-sysvmsg --enable-sysvsem --enable-sysvshm --enable-sockets --with-curl --with-curlwrappers --with-zlib --enable-zip --with-bz2 --with-gd --enable-gd-native-ttf --with-jpeg-dir --with-png-dir --with-freetype-dir --with-iconv-dir --with-readline
  3. #编译安装
  4. make && make install
  • 注意事项:
    参数 --prefix=/usr/local/php --with-config-file-scan-dir=/usr/local/php/etc/
    一定要设置正确,多个PHP版本须编译安装在不同路径!!!

可选项:--with-fpm-user=www --with-fpm-group=www
这里面开启了很多扩展。如果这时候忘了开启,以后还能加上吗?答案是可以的。以后只需要进入源码的ext目录,例如忘了pdo_mysql,进入ext/pdo_mysql,使用phpize工具,像安装普通扩展一样即可生成pdo_mysql.so。

关于:--enable-safe-mode
开启的话php可以执行一下系统函数,建议关闭(可搜索受此函数影响的php函数)。
如果只需要配置某一个目录可以执行则 设置为on并指定 safe_mode_exec_dir=string 目录来执行系统函数。本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。
safe_mode = off
php7编译不用加这个配置。编译比较耗内存和CPU,等待半小时左右编译完成。

三、配置文件

  1. 配置文件
    从安装包里复制php.ini、php-fpm.conf到安装目录或者自定义。

PHP5.6配置文件(安装后自行更改文件名):
php.ini:php安装目录/etc/php.ini
php-fpm:php安装目录/etc/php-fpm.conf

PHP7.2配置文件(安装后自行更改):
php.ini:php安装目录/etc/php.ini
php-fpm:php安装目录/etc/php-fpm.confphp安装目录/etc/php-fpm.d/www.conf

  1. 配置php.ini
# 不显示错误,默认
display_errors = Off
# 在关闭display_errors后开启PHP错误日志(路径在php-fpm.conf中配置),默认
log_errors = On
# 字符集,默认
default_charset = "UTF-8"
# 文件上传大小,默认值太小,建议修改10M
upload_max_filesize = 2M
# Maximum size of POST data that PHP will accept.  表单最大值,默认是8M,如果表单含有多图上传,大小可能不够。超过该大小后台收不到 表单数据
post_max_size = 8M  
# 设置PHP的扩展库路径,,默认被注释了。
extension_dir = "./ext/"
# 如果不设置extension_dir,也可以直接写绝对位置:
# extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20151012/redis.so
# 设置PHP的时区
date.timezone = PRC
# 开启opcache,默认是0
[opcache]
; Determines if Zend OPCache is enabled
opcache.enable=1
#函数禁用
disable_functions =exec,system,passthru,popen,pclose,shell_exec,proc_open,dl,chmod,popen
#将php.ini里的cgi.fix_pathinfo设置为0,不然会有漏洞。
cgi.fix_pathinfo=0
#更多扩展库根据需要自行添加
  1. 配置php-fpm.conf
    注:这里使用php7.2配置文件演示,其他版本PHP同理。
; 去掉里分号,方便以后重启。建议修改
; Default Value: none
; 下面的值最终目录是/usr/local/php/var/run/php-fpm.pid
; 开启后可以平滑重启php-fpm
pid = run/php-fpm.pid

; 设置错误日志的路径,可以默认值
; Note: the default prefix is /usr/local/php/var
; Default Value: log/php-fpm.log, 即/usr/local/php/var/log/php-fpm.log
error_log = /var/log/php-fpm/error.log

; Log等级,可以默认值
; Possible Values: alert, error, warning, notice, debug
; Default Value: notice
log_level = notice

; 后台运行,默认yes,可以默认值
; Default Value: yes
; daemonize = yes

; 引入www.conf文件中的配置,可以默认值
include=/usr/local/php/etc/php-fpm.d/*.conf

配置www.conf(在php-fpm.d目录下):
www.conf是php-fpm进程服务的扩展配置文件

; 设置运行用户和用户组,默认都是nobody。可以默认值
user = nginx
group = nginx

; 设置PHP监听
; 下面是默认值,不建议使用。可以默认值
; listen = 127.0.0.1:9000
listen = /tmp/php72.sock    //这里使用sock方式
; 根据nginx.conf中的配置fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
listen = /var/run/php-fpm/php-fpm.sock

;开启慢日志。可以默认值
slowlog = /var/log/php-fpm/$pool-slow.log
request_slowlog_timeout = 10s

;设置监听用户和用户组
listen.owner = www
listen.group = www
#listen.mode = 0660

保存配置文件后,检验配置是否正确的方法为:
/usr/local/php/sbin/php-fpm -t
如果出现诸如 test is successful 字样,说明配置没有问题。另外该命令也可以让我们知道php-fpm的配置文件在哪。

建立软连接:

ln -sf /usr/local/php/sbin/php-fpm /usr/bin/
ln -sf /usr/local/php/bin/php /usr/bin/
ln -sf /usr/local/php/bin/phpize /usr/bin/
ln -sf /usr/local/php/bin/php-config /usr/bin/
ln -sf /usr/local/php/bin/php-cig /usr/bin/

或者将php编译生成的bin目录添加到当前Linux系统的环境变量中:
echo -e '\nexport PATH=/usr/local/php/bin:/usr/local/php/sbin:$PATH\n' >> /etc/profile && source /etc/profile

注意事项:
若使用监听端口的方式,Nginx配置需要对应更改。
不同版本PHP监听不同端口或者scok文件。
使用sock方式时一定要正确设置对应sock文件的权限!!!
建议给www用户组的www用户赋予php-fpm.sock 的访问权限。

例(php-fpm配置文件):
php5.6(端口或sock二选一):

listen = 127.0.0.1:9000         //监听端口
listen = /tmp/php56.sock        //监听sock

php7.2(端口或sock二选一):

listen = 127.0.0.1:9001         //监听端口
listen = /tmp/php72.sock        //监听sock

注:Nginx配置见后文。

四、配置php-fpm启动文件

注:不同版本php使用不同文件名启动配置文件即可,并对应设置配置文件内相关路径。

  • php启动文件
    在目录 /etc/init.d/ 下新建文件命名为php56(可自定义)
    如下配置:
#! /bin/sh

### BEGIN INIT INFO
# Provides:          php-fpm
# Required-Start:    $remote_fs $network
# Required-Stop:     $remote_fs $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts php-fpm
# Description:       starts the PHP FastCGI Process Manager daemon
### END INIT INFO

#这里注意修改为对应版本php安装路径!!!
prefix=/serverw/php/php56       
exec_prefix=${prefix}

php_fpm_BIN=${exec_prefix}/sbin/php-fpm
php_fpm_CONF=${prefix}/etc/php-fpm.conf
php_fpm_PID=${prefix}/var/run/php-fpm.pid


php_opts="--fpm-config $php_fpm_CONF --pid $php_fpm_PID"


wait_for_pid () {
    try=0

    while test $try -lt 35 ; do

        case "$1" in
            'created')
            if [ -f "$2" ] ; then
                try=''
                break
            fi
            ;;

            'removed')
            if [ ! -f "$2" ] ; then
                try=''
                break
            fi
            ;;
        esac

        echo -n .
        try=`expr $try + 1`
        sleep 1

    done

}

case "$1" in
    start)
        echo -n "Starting php-fpm "

        $php_fpm_BIN --daemonize $php_opts

        if [ "$?" != 0 ] ; then
            echo " failed"
            exit 1
        fi

        wait_for_pid created $php_fpm_PID

        if [ -n "$try" ] ; then
            echo " failed"
            exit 1
        else
            echo " done"
        fi
    ;;

    stop)
        echo -n "Gracefully shutting down php-fpm "

        if [ ! -r $php_fpm_PID ] ; then
            echo "warning, no pid file found - php-fpm is not running ?"
            exit 1
        fi

        kill -QUIT `cat $php_fpm_PID`

        wait_for_pid removed $php_fpm_PID

        if [ -n "$try" ] ; then
            echo " failed. Use force-quit"
            exit 1
        else
            echo " done"
        fi
    ;;

    status)
        if [ ! -r $php_fpm_PID ] ; then
            echo "php-fpm is stopped"
            exit 0
        fi

        PID=`cat $php_fpm_PID`
        if ps -p $PID | grep -q $PID; then
            echo "php-fpm (pid $PID) is running..."
        else
            echo "php-fpm dead but pid file exists"
        fi
    ;;

    force-quit)
        echo -n "Terminating php-fpm "

        if [ ! -r $php_fpm_PID ] ; then
            echo "warning, no pid file found - php-fpm is not running ?"
            exit 1
        fi

        kill -TERM `cat $php_fpm_PID`

        wait_for_pid removed $php_fpm_PID

        if [ -n "$try" ] ; then
            echo " failed"
            exit 1
        else
            echo " done"
        fi
    ;;

    restart)
        $0 stop
        $0 start
    ;;

    reload)

        echo -n "Reload service php-fpm "

        if [ ! -r $php_fpm_PID ] ; then
            echo "warning, no pid file found - php-fpm is not running ?"
            exit 1
        fi

        kill -USR2 `cat $php_fpm_PID`

        echo " done"
    ;;

    *)
        echo "Usage: $0 {start|stop|force-quit|restart|reload|status}"
        exit 1
    ;;

esac

php其他版本启动配置文件同理,不再赘述。

配置完后启动php对应版本命令:

/etc/init.d/php56 start     //启动
/etc/init.d/php56 stop      //停止
/etc/init.d/php56 restart   //重启
/etc/init.d/php56 reload    //重载配置
/etc/init.d/php56 status    //运行状态

五、Nginx配置(自行安装)

Nginx配置文件:/Nginx安装目录/nginx.conf
站点配置文件:Nginx安装目录/conf.d/default

  • 配置Nginx运行账户及文件上传(nginx.conf):
#用户名 用户组
user www www;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections  1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    #nginx文件上传大小
    client_max_body_size 50m;
    #nginx文件缓存目录
    client_body_temp_path /tmp/nginx_temp;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;
}
  • 配置站点(default.conf):
#
# The default server
#

#站点一配置
server
{
#nginx监听端口
listen 80; 
#访问域名
server_name www.aaa.com aaa.com;
#默认文档
index index.html index.htm index.php default.html default.htm default.php;
#站点目录及404错误页
root /wwwroot/aaa/;
#error_page 404 /404.html;
#加载php
location ~ [^/]\.php(/|$)
{
# comment try_files $uri =404; to enable pathinfo
try_files $uri =404;
#监听sock方式
fastcgi_pass unix:/tmp/php56.sock;
#监听端口方式
#fastcgi_pass 127.0.0.1:9000;

fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#防止跨目录
fastcgi_param PHP_ADMIN_VALUE "open_basedir=/wwwroot/bbb/:/tmp/:/proc/";
include fastcgi_params;
#include pathinfo.conf;
}

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}

location ~ .*\.(js|css)?$
{
expires 12h;
}

# access_log /wwwroot/wwwlogs/aaa.log main;
}

#站点二配置
server
{
listen 81;
server_name www.bbb.com bbb.com;
index index.html index.htm index.php default.html default.htm default.php;
root /wwwroot/bbb/;
#error_page 404 /404.html;
location ~ [^/]\.php(/|$)
{
# comment try_files $uri =404; to enable pathinfo
try_files $uri =404;

#设置监听方式
fastcgi_pass unix:/tmp/php72.sock;
#fastcgi_pass 127.0.0.1:9001;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#防止跨目录
fastcgi_param PHP_ADMIN_VALUE "open_basedir=/wwwroot/bbb/:/tmp/:/proc/";
include fastcgi_params;
#include pathinfo.conf;
}

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}

location ~ .*\.(js|css)?$
{
expires 12h;
}

# access_log /wwwroot/wwwlogs/bbb.log main;
}
  • 配置完后重启nginx:
    /etc/init.d/nginx restart
    检查配置是否成功:
    分别在两个站点建立phpinfo文件查看对应信息。