一、前言
为了应对不同的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
#编译参数
./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
#编译安装
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,等待半小时左右编译完成。
三、配置文件
-
配置文件
从安装包里复制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.conf
或php安装目录/etc/php-fpm.d/www.conf
配置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
#更多扩展库根据需要自行添加
- 配置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文件查看对应信息。