diff --git a/compatibility.md b/compatibility.md
index 51c26be02..55efff332 100644
--- a/compatibility.md
+++ b/compatibility.md
@@ -53,7 +53,7 @@ cd /www/server/mdserver-web/plugins/php && bash all_test.sh
| CentOS 8.4 |:x: |✅ |✅ |✅ |
| CentOS 8 Stream |✅ |✅ |✅ |✅ |
| CentOS 9 Stream |✅ |:x: |:x: |:x: |
-| Debian 10.3 |✅ |✅ |✅ |✅ |
+| Debian 10.3 |✅ |✅ |✅ |:x: |
| Debian 11.3 |✅ |✅ |✅ |✅ |
| Ubuntu 10.04 |✅ |✅ |✅ |✅ |
| Ubuntu 11.3 |✅ |✅ |✅ |✅ |
diff --git a/plugins/php-apt/all_test.sh b/plugins/php-apt/all_test.sh
new file mode 100644
index 000000000..59bd64c08
--- /dev/null
+++ b/plugins/php-apt/all_test.sh
@@ -0,0 +1,53 @@
+#! /bin/sh
+export PATH=$PATH:/opt/local/bin:/opt/local/sbin:/opt/local/share/man:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin
+DIR=$(cd "$(dirname "$0")"; pwd)
+
+
+
+# cd /www/server/mdserver-web/scripts/quick && bash debug.sh
+# cd /www/server/mdserver-web/plugins/php && bash all_test.sh
+
+
+# cd /www/server/mdserver-web/plugins/php && bash install.sh install 71
+# cd /www/server/mdserver-web/plugins/php/versions/52/ && bash gd.sh install 52
+
+# cd /www/server/mdserver-web/plugins/php/versions/52/ && bash openssl.sh install 52
+# cd /www/server/mdserver-web/plugins/php/versions/81/ && bash imagemagick.sh install 81
+# cd /www/server/mdserver-web/plugins/php/versions/70/ && bash imagemagick.sh install 70
+
+PHP_VER=71
+echo "php${PHP_VER} -- start"
+cmd_ext=$(ls -l $DIR/versions/$PHP_VER/ |awk '{print $9}')
+cd $DIR && /bin/bash install.sh install $PHP_VER
+for ii in $cmd_ext
+do
+ if [ "install.sh" == "$ii" ];then
+ echo '' > /tmp/t.log
+ else
+ cd $DIR/versions/$PHP_VER && /bin/bash $ii install $PHP_VER
+ fi
+done
+echo "php${PHP_VER} -- end"
+
+
+PHP_VER_LIST=(53 54 55 56 70 71 72 73 74 80 81)
+# PHP_VER_LIST=(81)
+for PHP_VER in ${PHP_VER_LIST[@]}; do
+ echo "php${PHP_VER} -- start"
+ if [ -d /www/server/php/${PHP_VER} ];then
+ cmd_ext=$(ls -l $DIR/versions/$PHP_VER/ |awk '{print $9}')
+ for ii in $cmd_ext
+ do
+ echo "${ii}"
+ if [ "install.sh" == "$ii" ];then
+ echo '' > /tmp/t.log
+ else
+ cd $DIR/versions/$PHP_VER/ && bash $ii install ${PHP_VER}
+ fi
+ done
+ fi
+ echo "php${PHP_VER} -- end"
+done
+
+
+rm -rf /tmp/t.log
diff --git a/plugins/php-apt/conf/enable-php.conf b/plugins/php-apt/conf/enable-php.conf
new file mode 100644
index 000000000..9f8461da7
--- /dev/null
+++ b/plugins/php-apt/conf/enable-php.conf
@@ -0,0 +1,9 @@
+set $PHP_ENV 1;
+location ~ [^/]\.php(/|$)
+{
+ try_files $uri =404;
+ fastcgi_pass unix:/var/opt/remi/php{$PHP_VERSION}/run/php-fpm/www.sock;
+ fastcgi_index index.php;
+ include fastcgi.conf;
+ include {$SERVER_PATH}/web_conf/php/pathinfo.conf;
+}
\ No newline at end of file
diff --git a/plugins/php-apt/conf/pathinfo.conf b/plugins/php-apt/conf/pathinfo.conf
new file mode 100644
index 000000000..47b573684
--- /dev/null
+++ b/plugins/php-apt/conf/pathinfo.conf
@@ -0,0 +1,8 @@
+set $real_script_name $fastcgi_script_name;
+if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
+ set $real_script_name $1;
+ set $path_info $2;
+ }
+fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;
+fastcgi_param SCRIPT_NAME $real_script_name;
+fastcgi_param PATH_INFO $path_info;
\ No newline at end of file
diff --git a/plugins/php-apt/conf/phpfpm_status.conf b/plugins/php-apt/conf/phpfpm_status.conf
new file mode 100644
index 000000000..aebdfae8f
--- /dev/null
+++ b/plugins/php-apt/conf/phpfpm_status.conf
@@ -0,0 +1,5 @@
+location /phpfpm_status_yum{$PHP_VERSION} {
+ fastcgi_pass unix:/var/opt/remi/php{$PHP_VERSION}/run/php-fpm/www.sock;
+ include fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME \$fastcgi_script_name;
+}
\ No newline at end of file
diff --git a/plugins/php-apt/conf/phpinfo.conf b/plugins/php-apt/conf/phpinfo.conf
new file mode 100644
index 000000000..b3c51e657
--- /dev/null
+++ b/plugins/php-apt/conf/phpinfo.conf
@@ -0,0 +1,4 @@
+location /{$PHP_VERSION} {
+ root {$ROOT_PATH}/phpinfo;
+ include {$SERVER_PATH}/web_conf/php/conf/enable-php-yum{$PHP_VERSION}.conf;
+}
\ No newline at end of file
diff --git a/plugins/php-apt/conf/www.conf b/plugins/php-apt/conf/www.conf
new file mode 100644
index 000000000..47b8349e4
--- /dev/null
+++ b/plugins/php-apt/conf/www.conf
@@ -0,0 +1,19 @@
+[www]
+user = {$PHP_USER}
+group = {$PHP_GROUP}
+
+listen = /var/opt/remi/php{$PHP_VERSION}/run/php-fpm/www.sock
+listen.owner = {$PHP_USER}
+listen.group = {$PHP_GROUP}
+pm = dynamic
+pm.max_children = 50
+pm.start_servers = 5
+pm.min_spare_servers = 5
+pm.max_spare_servers = 35
+pm.status_path = /phpfpm_status_yum{$PHP_VERSION}
+request_terminate_timeout = 100
+request_slowlog_timeout = 30
+slowlog = /var/opt/remi/php{$PHP_VERSION}/log/php-fpm/www-slow.log
+
+php_admin_flag[log_errors] = on
+php_admin_value[error_log] = /var/opt/remi/php{$PHP_VERSION}/log/php-fpm/error.log
\ No newline at end of file
diff --git a/plugins/php-apt/ico.png b/plugins/php-apt/ico.png
new file mode 100755
index 000000000..59def5702
Binary files /dev/null and b/plugins/php-apt/ico.png differ
diff --git a/plugins/php-apt/index.html b/plugins/php-apt/index.html
new file mode 100755
index 000000000..790f56c06
--- /dev/null
+++ b/plugins/php-apt/index.html
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/plugins/php-apt/index.py b/plugins/php-apt/index.py
new file mode 100755
index 000000000..e992f3c99
--- /dev/null
+++ b/plugins/php-apt/index.py
@@ -0,0 +1,714 @@
+# coding:utf-8
+
+import sys
+import io
+import os
+import time
+import re
+import json
+import shutil
+
+
+sys.path.append(os.getcwd() + "/class/core")
+import mw
+
+if mw.isAppleSystem():
+ cmd = 'ls /usr/local/lib/ | grep python | cut -d \\ -f 1 | awk \'END {print}\''
+ info = mw.execShell(cmd)
+ p = "/usr/local/lib/" + info[0].strip() + "/site-packages"
+ sys.path.append(p)
+
+app_debug = False
+if mw.isAppleSystem():
+ app_debug = True
+
+
+def getPluginName():
+ return 'php-apt'
+
+
+def getServerDir():
+ return '/etc/opt/remi'
+
+
+def getPluginDir():
+ return mw.getPluginDir() + '/' + getPluginName()
+
+
+def getArgs():
+ args = sys.argv[3:]
+ tmp = {}
+ args_len = len(args)
+
+ if args_len == 1:
+ t = args[0].strip('{').strip('}')
+ t = t.split(':')
+ tmp[t[0]] = t[1]
+ elif args_len > 1:
+ for i in range(len(args)):
+ t = args[i].split(':')
+ tmp[t[0]] = t[1]
+
+ return tmp
+
+
+def checkArgs(data, ck=[]):
+ for i in range(len(ck)):
+ if not ck[i] in data:
+ return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
+ return (True, mw.returnJson(True, 'ok'))
+
+
+def getConf(version):
+ path = getServerDir() + '/php' + version + '/php.ini'
+ return path
+
+
+def status(version):
+ # ps -ef|grep 'php/81' |grep -v grep | grep -v python | awk '{print $2}
+ cmd = "ps -ef|grep 'remi/php" + version + \
+ "' |grep -v grep | grep -v python | awk '{print $2}'"
+ data = mw.execShell(cmd)
+ if data[0] == '':
+ return 'stop'
+ return 'start'
+
+
+def contentReplace(content, version):
+ service_path = mw.getServerDir()
+ content = content.replace('{$ROOT_PATH}', mw.getRootDir())
+ content = content.replace('{$SERVER_PATH}', service_path)
+ content = content.replace('{$PHP_VERSION}', version)
+ content = content.replace('{$LOCAL_IP}', mw.getLocalIp())
+
+ if mw.isAppleSystem():
+ # user = mw.execShell(
+ # "who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
+ content = content.replace('{$PHP_USER}', 'nobody')
+ content = content.replace('{$PHP_GROUP}', 'nobody')
+
+ rep = 'listen.owner\s*=\s*(.+)\r?\n'
+ val = ';listen.owner = nobody\n'
+ content = re.sub(rep, val, content)
+
+ rep = 'listen.group\s*=\s*(.+)\r?\n'
+ val = ';listen.group = nobody\n'
+ content = re.sub(rep, val, content)
+
+ rep = 'user\s*=\s*(.+)\r?\n'
+ val = ';user = nobody\n'
+ content = re.sub(rep, val, content)
+
+ rep = r'[^\.]group\s*=\s*(.+)\r?\n'
+ val = ';group = nobody\n'
+ content = re.sub(rep, val, content)
+
+ else:
+ content = content.replace('{$PHP_USER}', 'www')
+ content = content.replace('{$PHP_GROUP}', 'www')
+ return content
+
+
+def makeOpenrestyConf(version):
+
+ sdir = mw.getServerDir()
+ d_pathinfo = sdir + '/web_conf/php/pathinfo.conf'
+ if not os.path.exists(d_pathinfo):
+ s_pathinfo = getPluginDir() + '/conf/pathinfo.conf'
+ shutil.copyfile(s_pathinfo, d_pathinfo)
+
+ dst_dir = sdir + '/web_conf/php'
+ dst_dir_conf = sdir + '/web_conf/php/conf'
+ dst_dir_status = sdir + '/web_conf/php/status'
+ if not os.path.exists(dst_dir):
+ mw.execShell('mkdir -p ' + dst_dir)
+
+ if not os.path.exists(dst_dir_conf):
+ mw.execShell('mkdir -p ' + dst_dir_conf)
+
+ if not os.path.exists(dst_dir_status):
+ mw.execShell('mkdir -p ' + dst_dir_status)
+
+ info = getPluginDir() + '/info.json'
+ content = mw.readFile(info)
+ content = json.loads(content)
+ versions = content['versions']
+ tpl = getPluginDir() + '/conf/enable-php.conf'
+ tpl_content = mw.readFile(tpl)
+ dfile = sdir + '/web_conf/php/conf/enable-php-yum' + version + '.conf'
+ if not os.path.exists(dfile):
+ w_content = contentReplace(tpl_content, version)
+ mw.writeFile(dfile, w_content)
+
+ # php-fpm status
+ dfile = sdir + '/web_conf/php/status/phpfpm_status_yum' + version + '.conf'
+ tpl = getPluginDir() + '/conf/phpfpm_status.conf'
+ if not os.path.exists(dfile):
+ content = mw.readFile(tpl)
+ content = contentReplace(content, version)
+ mw.writeFile(dfile, content)
+
+
+def phpFpmWwwReplace(version):
+ service_php_fpm_dir = getServerDir() + '/php' + version + '/php-fpm.d/'
+ if not os.path.exists(service_php_fpm_dir):
+ os.mkdir(service_php_fpm_dir)
+
+ service_php_fpmwww = service_php_fpm_dir + '/www.conf'
+ if os.path.exists(service_php_fpmwww):
+ # 原来文件备份
+ mw.execShell('mv ' + service_php_fpmwww +
+ ' ' + service_php_fpmwww + '.bak')
+
+ service_php_fpm_mw = service_php_fpm_dir + '/mw.conf'
+ if not os.path.exists(service_php_fpm_mw):
+ tpl_php_fpmwww = getPluginDir() + '/conf/www.conf'
+ content = mw.readFile(tpl_php_fpmwww)
+ content = contentReplace(content, version)
+ mw.writeFile(service_php_fpm_mw, content)
+
+
+def getFpmConfFile(version):
+ return getServerDir() + '/php' + version + '/php-fpm.d/mw.conf'
+
+
+def deleteConfList(version):
+ sdir = mw.getServerDir()
+ enable_conf = sdir + '/web_conf/php/conf/enable-php-yum' + version + '.conf'
+ status_conf = sdir + '/web_conf/php/status/phpfpm_status_yum' + version + '.conf'
+
+ clist = (status_conf, enable_conf)
+ for f in clist:
+ if os.path.exists(f):
+ os.remove(f)
+
+
+def initReplace(version):
+ makeOpenrestyConf(version)
+ phpFpmWwwReplace(version)
+
+ # systemd
+ # mw.execShell('systemctl daemon-reload')
+ return 'ok'
+
+
+def phpOp(version, method):
+ if method == 'start':
+ initReplace(version)
+
+ if mw.isAppleSystem():
+ return 'fail'
+ data = mw.execShell('systemctl ' + method + ' ' +
+ 'php' + version + '-php-fpm')
+ if data[1] == '':
+ return 'ok'
+ return data[1]
+
+
+def start(version):
+ return phpOp(version, 'start')
+
+
+def stop(version):
+ status = phpOp(version, 'stop')
+ deleteConfList(version)
+ return status
+
+
+def restart(version):
+ return phpOp(version, 'restart')
+
+
+def reload(version):
+ return phpOp(version, 'reload')
+
+
+def initdStatus(version):
+ if mw.isAppleSystem():
+ return "Apple Computer does not support"
+
+ shell_cmd = 'systemctl status php' + version + \
+ '-php-fpm | grep loaded | grep "enabled;"'
+ data = mw.execShell(shell_cmd)
+ if data[0] == '':
+ return 'fail'
+ return 'ok'
+
+
+def initdInstall(version):
+ if mw.isAppleSystem():
+ return "Apple Computer does not support"
+
+ mw.execShell('systemctl enable php' + version + '-php-fpm')
+ return 'ok'
+
+
+def initdUinstall(version):
+ if mw.isAppleSystem():
+ return "Apple Computer does not support"
+
+ mw.execShell('systemctl disable php' + version + '-php-fpm')
+ return 'ok'
+
+
+def fpmLog(version):
+ return '/var/opt/remi/php' + version + '/log/php-fpm/error.log'
+
+
+def fpmSlowLog(version):
+ return '/var/opt/remi/php' + version + '/log/php-fpm/www-slow.log'
+
+
+def getPhpConf(version):
+ gets = [
+ {'name': 'short_open_tag', 'type': 1, 'ps': '短标签支持'},
+ {'name': 'asp_tags', 'type': 1, 'ps': 'ASP标签支持'},
+ {'name': 'max_execution_time', 'type': 2, 'ps': '最大脚本运行时间'},
+ {'name': 'max_input_time', 'type': 2, 'ps': '最大输入时间'},
+ {'name': 'max_input_vars', 'type': 2, 'ps': '最大输入数量'},
+ {'name': 'memory_limit', 'type': 2, 'ps': '脚本内存限制'},
+ {'name': 'post_max_size', 'type': 2, 'ps': 'POST数据最大尺寸'},
+ {'name': 'file_uploads', 'type': 1, 'ps': '是否允许上传文件'},
+ {'name': 'upload_max_filesize', 'type': 2, 'ps': '允许上传文件的最大尺寸'},
+ {'name': 'max_file_uploads', 'type': 2, 'ps': '允许同时上传文件的最大数量'},
+ {'name': 'default_socket_timeout', 'type': 2, 'ps': 'Socket超时时间'},
+ {'name': 'error_reporting', 'type': 3, 'ps': '错误级别'},
+ {'name': 'display_errors', 'type': 1, 'ps': '是否输出详细错误信息'},
+ {'name': 'cgi.fix_pathinfo', 'type': 0, 'ps': '是否开启pathinfo'},
+ {'name': 'date.timezone', 'type': 3, 'ps': '时区'}
+ ]
+ phpini = mw.readFile(getConf(version))
+ result = []
+ for g in gets:
+ rep = g['name'] + '\s*=\s*([0-9A-Za-z_& ~]+)(\s*;?|\r?\n)'
+ tmp = re.search(rep, phpini)
+ if not tmp:
+ continue
+ g['value'] = tmp.groups()[0]
+ result.append(g)
+ return mw.getJson(result)
+
+
+def submitPhpConf(version):
+ gets = ['display_errors', 'cgi.fix_pathinfo', 'date.timezone', 'short_open_tag',
+ 'asp_tags', 'max_execution_time', 'max_input_time', 'max_input_vars', 'memory_limit',
+ 'post_max_size', 'file_uploads', 'upload_max_filesize', 'max_file_uploads',
+ 'default_socket_timeout', 'error_reporting']
+ args = getArgs()
+ filename = getConf(version)
+ phpini = mw.readFile(filename)
+ for g in gets:
+ if g in args:
+ rep = g + '\s*=\s*(.+)\r?\n'
+ val = g + ' = ' + args[g] + '\n'
+ phpini = re.sub(rep, val, phpini)
+ mw.writeFile(filename, phpini)
+ reload(version)
+ return mw.returnJson(True, '设置成功')
+
+
+def getLimitConf(version):
+ fileini = getConf(version)
+ phpini = mw.readFile(fileini)
+ filefpm = getFpmConfFile(version)
+ phpfpm = mw.readFile(filefpm)
+
+ # print fileini, filefpm
+ data = {}
+ try:
+ rep = "upload_max_filesize\s*=\s*([0-9]+)M"
+ tmp = re.search(rep, phpini).groups()
+ data['max'] = tmp[0]
+ except:
+ data['max'] = '50'
+
+ try:
+ rep = "request_terminate_timeout\s*=\s*([0-9]+)\n"
+ tmp = re.search(rep, phpfpm).groups()
+ data['maxTime'] = tmp[0]
+ except:
+ data['maxTime'] = 0
+
+ try:
+ rep = r"\n;*\s*cgi\.fix_pathinfo\s*=\s*([0-9]+)\s*\n"
+ tmp = re.search(rep, phpini).groups()
+
+ if tmp[0] == '1':
+ data['pathinfo'] = True
+ else:
+ data['pathinfo'] = False
+ except:
+ data['pathinfo'] = False
+
+ return mw.getJson(data)
+
+
+def setMaxTime(version):
+ args = getArgs()
+ data = checkArgs(args, ['time'])
+ if not data[0]:
+ return data[1]
+
+ time = args['time']
+ if int(time) < 30 or int(time) > 86400:
+ return mw.returnJson(False, '请填写30-86400间的值!')
+
+ filefpm = getFpmConfFile(version)
+ conf = mw.readFile(filefpm)
+ rep = "request_terminate_timeout\s*=\s*([0-9]+)\n"
+ conf = re.sub(rep, "request_terminate_timeout = " + time + "\n", conf)
+ mw.writeFile(filefpm, conf)
+
+ fileini = getConf(version)
+ phpini = mw.readFile(fileini)
+ rep = "max_execution_time\s*=\s*([0-9]+)\r?\n"
+ phpini = re.sub(rep, "max_execution_time = " + time + "\n", phpini)
+ rep = "max_input_time\s*=\s*([0-9]+)\r?\n"
+ phpini = re.sub(rep, "max_input_time = " + time + "\n", phpini)
+ mw.writeFile(fileini, phpini)
+ return mw.returnJson(True, '设置成功!')
+
+
+def setMaxSize(version):
+ args = getArgs()
+ data = checkArgs(args, ['max'])
+ if not data[0]:
+ return data[1]
+
+ maxVal = args['max']
+ if int(maxVal) < 2:
+ return mw.returnJson(False, '上传大小限制不能小于2MB!')
+
+ path = getConf(version)
+ conf = mw.readFile(path)
+ rep = u"\nupload_max_filesize\s*=\s*[0-9]+M"
+ conf = re.sub(rep, u'\nupload_max_filesize = ' + maxVal + 'M', conf)
+ rep = u"\npost_max_size\s*=\s*[0-9]+M"
+ conf = re.sub(rep, u'\npost_max_size = ' + maxVal + 'M', conf)
+ mw.writeFile(path, conf)
+
+ msg = mw.getInfo('设置PHP-{1}最大上传大小为[{2}MB]!', (version, maxVal,))
+ mw.writeLog('插件管理[PHP]', msg)
+ return mw.returnJson(True, '设置成功!')
+
+
+def getFpmConfig(version):
+
+ filefpm = getFpmConfFile(version)
+ conf = mw.readFile(filefpm)
+ data = {}
+ rep = "\s*pm.max_children\s*=\s*([0-9]+)\s*"
+ tmp = re.search(rep, conf).groups()
+ data['max_children'] = tmp[0]
+
+ rep = "\s*pm.start_servers\s*=\s*([0-9]+)\s*"
+ tmp = re.search(rep, conf).groups()
+ data['start_servers'] = tmp[0]
+
+ rep = "\s*pm.min_spare_servers\s*=\s*([0-9]+)\s*"
+ tmp = re.search(rep, conf).groups()
+ data['min_spare_servers'] = tmp[0]
+
+ rep = "\s*pm.max_spare_servers \s*=\s*([0-9]+)\s*"
+ tmp = re.search(rep, conf).groups()
+ data['max_spare_servers'] = tmp[0]
+
+ rep = "\s*pm\s*=\s*(\w+)\s*"
+ tmp = re.search(rep, conf).groups()
+ data['pm'] = tmp[0]
+ return mw.getJson(data)
+
+
+def setFpmConfig(version):
+ args = getArgs()
+ # if not 'max' in args:
+ # return 'missing time args!'
+
+ version = args['version']
+ max_children = args['max_children']
+ start_servers = args['start_servers']
+ min_spare_servers = args['min_spare_servers']
+ max_spare_servers = args['max_spare_servers']
+ pm = args['pm']
+
+ file = getServerDir() + '/php' + version + '/php-fpm.d/www.conf'
+ conf = mw.readFile(file)
+
+ rep = "\s*pm.max_children\s*=\s*([0-9]+)\s*"
+ conf = re.sub(rep, "\npm.max_children = " + max_children, conf)
+
+ rep = "\s*pm.start_servers\s*=\s*([0-9]+)\s*"
+ conf = re.sub(rep, "\npm.start_servers = " + start_servers, conf)
+
+ rep = "\s*pm.min_spare_servers\s*=\s*([0-9]+)\s*"
+ conf = re.sub(rep, "\npm.min_spare_servers = " +
+ min_spare_servers, conf)
+
+ rep = "\s*pm.max_spare_servers \s*=\s*([0-9]+)\s*"
+ conf = re.sub(rep, "\npm.max_spare_servers = " +
+ max_spare_servers + "\n", conf)
+
+ rep = "\s*pm\s*=\s*(\w+)\s*"
+ conf = re.sub(rep, "\npm = " + pm + "\n", conf)
+
+ mw.writeFile(file, conf)
+ reload(version)
+
+ msg = mw.getInfo('设置PHP-{1}并发设置,max_children={2},start_servers={3},min_spare_servers={4},max_spare_servers={5}', (version, max_children,
+ start_servers, min_spare_servers, max_spare_servers,))
+ mw.writeLog('插件管理[PHP]', msg)
+ return mw.returnJson(True, '设置成功!')
+
+
+def checkFpmStatusFile(version):
+ if not mw.isInstalledWeb():
+ return False
+
+ dfile = getServerDir() + '/nginx/conf/php_status/phpfpm_status_yum' + version + '.conf'
+ if not os.path.exists(dfile):
+ tpl = getPluginDir() + '/conf/phpfpm_status.conf'
+ content = mw.readFile(tpl)
+ content = contentReplace(content, version)
+ mw.writeFile(dfile, content)
+ mw.restartWeb()
+ return True
+
+
+def getFpmStatus(version):
+
+ checkFpmStatusFile(version)
+ stat = status(version)
+ if stat == 'stop':
+ return mw.returnJson(False, 'PHP[' + version + ']未启动!!!')
+
+ try:
+ url = 'http://' + mw.getHostAddr() + '/phpfpm_status_yum' + version + '?json'
+ result = mw.httpGet(url, 1)
+ data = json.loads(result)
+ fTime = time.localtime(int(data['start time']))
+ data['start time'] = time.strftime('%Y-%m-%d %H:%M:%S', fTime)
+ except Exception as e:
+ url = 'http://127.0.0.1/phpfpm_status_yum' + version + '?json'
+ result = mw.httpGet(url, 1)
+ data = json.loads(result)
+ fTime = time.localtime(int(data['start time']))
+ data['start time'] = time.strftime('%Y-%m-%d %H:%M:%S', fTime)
+ except Exception as e:
+ data = {}
+
+ return mw.returnJson(True, "OK", data)
+
+
+def getDisableFunc(version):
+ filename = getConf(version)
+ if not os.path.exists(filename):
+ return mw.returnJson(False, '指定PHP版本不存在!')
+
+ phpini = mw.readFile(filename)
+ data = {}
+ rep = "disable_functions\s*=\s{0,1}(.*)\n"
+ tmp = re.search(rep, phpini).groups()
+ data['disable_functions'] = tmp[0]
+ return mw.getJson(data)
+
+
+def setDisableFunc(version):
+ filename = getConf(version)
+ if not os.path.exists(filename):
+ return mw.returnJson(False, '指定PHP版本不存在!')
+
+ args = getArgs()
+ disable_functions = args['disable_functions']
+
+ phpini = mw.readFile(filename)
+ rep = "disable_functions\s*=\s*.*\n"
+ phpini = re.sub(rep, 'disable_functions = ' +
+ disable_functions + "\n", phpini)
+
+ msg = mw.getInfo('修改PHP-{1}的禁用函数为[{2}]', (version, disable_functions,))
+ mw.writeLog('插件管理[PHP-YUM]', msg)
+ mw.writeFile(filename, phpini)
+ reload(version)
+ return mw.returnJson(True, '设置成功!')
+
+
+def checkPhpinfoFile(v):
+ sdir = mw.getServerDir()
+ dfile = sdir + '/web_conf/php/status/phpinfo_' + v + '.conf'
+ tpl = getPluginDir() + '/conf/phpinfo.conf'
+ content = mw.readFile(tpl)
+ content = contentReplace(content, v)
+ mw.writeFile(dfile, content)
+ mw.restartWeb()
+
+
+def getPhpinfo(v):
+ checkPhpinfoFile(v)
+ sPath = mw.getRootDir() + '/phpinfo/' + v
+
+ mw.execShell("rm -rf " + mw.getRootDir() + '/phpinfo')
+ mw.execShell("mkdir -p " + sPath)
+ mw.writeFile(sPath + '/phpinfo.php', '')
+ url = 'http://127.0.0.1/' + v + '/phpinfo.php'
+ phpinfo = mw.httpGet(url)
+ os.system("rm -rf " + mw.getRootDir() + '/phpinfo')
+ return phpinfo
+
+
+def get_php_info(args):
+ if not mw.isInstalledWeb():
+ return "openresty is not running!!!"
+ return getPhpinfo(args['version'])
+
+
+def getLibConf(version):
+ fname = getConf(version)
+ if not os.path.exists(fname):
+ return mw.returnJson(False, '指定PHP版本不存在!')
+
+ # phpini = mw.readFile(fname)
+ content = mw.execShell('cat /etc/opt/remi/php' +
+ version + "/php.d/* | grep -v '^;' |tr -s '\n'")
+ content = content[0]
+
+ libpath = getPluginDir() + '/versions/phplib.conf'
+ phplib = json.loads(mw.readFile(libpath))
+
+ libs = []
+ tasks = mw.M('tasks').where(
+ "status!=?", ('1',)).field('status,name').select()
+ for lib in phplib:
+ lib['task'] = '1'
+ for task in tasks:
+ tmp = mw.getStrBetween('[', ']', task['name'])
+ if not tmp:
+ continue
+ tmp1 = tmp.split('-')
+ if tmp1[0].lower() == lib['name'].lower():
+ lib['task'] = task['status']
+ lib['phpversions'] = []
+ lib['phpversions'].append(tmp1[1])
+ if content.find(lib['check']) == -1:
+ lib['status'] = False
+ else:
+ lib['status'] = True
+ libs.append(lib)
+ return mw.returnJson(True, 'OK!', libs)
+
+
+def installLib(version):
+ args = getArgs()
+ data = checkArgs(args, ['name'])
+ if not data[0]:
+ return data[1]
+
+ name = args['name']
+ execstr = "cd " + getPluginDir() + '/versions/' + \
+ " && /bin/bash common.sh " + version + ' install ' + name
+
+ rettime = time.strftime('%Y-%m-%d %H:%M:%S')
+ insert_info = (None, '安装PHPYUM[' + name + '-' + version + ']',
+ 'execshell', '0', rettime, execstr)
+ mw.M('tasks').add('id,name,type,status,addtime,execstr', insert_info)
+
+ mw.triggerTask()
+ return mw.returnJson(True, '已将下载任务添加到队列!')
+
+
+def uninstallLib(version):
+ args = getArgs()
+ data = checkArgs(args, ['name'])
+ if not data[0]:
+ return data[1]
+
+ name = args['name']
+ execstr = "cd " + getPluginDir() + '/versions/' + \
+ " && /bin/bash common.sh " + version + ' uninstall ' + name
+
+ data = mw.execShell(execstr)
+ # data[0] == '' and
+ if data[1] == '':
+ return mw.returnJson(True, '已经卸载成功!')
+ else:
+ return mw.returnJson(False, '卸载错误信息!:' + data[1])
+
+
+def installPreInspection(version):
+ sys = mw.execShell(
+ "cat /etc/*-release | grep PRETTY_NAME |awk -F = '{print $2}' | awk -F '\"' '{print $2}'| awk '{print $1}'")
+
+ sys_id = mw.execShell(
+ "cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F '\"' '{print $2}'")
+
+ sysName = sys[0].strip().lower()
+ sysId = sys_id[0].strip()
+
+ if not sysName in ('centos'):
+ return '暂时仅支持centos'
+ return 'ok'
+
+if __name__ == "__main__":
+
+ if len(sys.argv) < 3:
+ print('missing parameters')
+ exit(0)
+
+ func = sys.argv[1]
+ version = sys.argv[2]
+
+ if func == 'status':
+ print(status(version))
+ elif func == 'start':
+ print(start(version))
+ elif func == 'stop':
+ print(stop(version))
+ elif func == 'restart':
+ print(restart(version))
+ elif func == 'reload':
+ print(reload(version))
+ elif func == 'install_pre_inspection':
+ print(installPreInspection(version))
+ elif func == 'initd_status':
+ print(initdStatus(version))
+ elif func == 'initd_install':
+ print(initdInstall(version))
+ elif func == 'initd_uninstall':
+ print(initdUinstall(version))
+ elif func == 'fpm_log':
+ print(fpmLog(version))
+ elif func == 'fpm_slow_log':
+ print(fpmSlowLog(version))
+ elif func == 'conf':
+ print(getConf(version))
+ elif func == 'get_php_conf':
+ print(getPhpConf(version))
+ elif func == 'get_fpm_conf_file':
+ print(getFpmConfFile(version))
+ elif func == 'submit_php_conf':
+ print(submitPhpConf(version))
+ elif func == 'get_limit_conf':
+ print(getLimitConf(version))
+ elif func == 'set_max_time':
+ print(setMaxTime(version))
+ elif func == 'set_max_size':
+ print(setMaxSize(version))
+ elif func == 'get_fpm_conf':
+ print(getFpmConfig(version))
+ elif func == 'set_fpm_conf':
+ print(setFpmConfig(version))
+ elif func == 'get_fpm_status':
+ print(getFpmStatus(version))
+ elif func == 'get_disable_func':
+ print(getDisableFunc(version))
+ elif func == 'set_disable_func':
+ print(setDisableFunc(version))
+ elif func == 'get_phpinfo':
+ print(getPhpinfo(version))
+ elif func == 'get_lib_conf':
+ print(getLibConf(version))
+ elif func == 'install_lib':
+ print(installLib(version))
+ elif func == 'uninstall_lib':
+ print(uninstallLib(version))
+ else:
+ print("fail")
diff --git a/plugins/php-apt/info.json b/plugins/php-apt/info.json
new file mode 100755
index 000000000..a74526b00
--- /dev/null
+++ b/plugins/php-apt/info.json
@@ -0,0 +1,19 @@
+{
+ "sort": 7,
+ "ps": "PHP是世界上最好的编程语言[APT]",
+ "shell": "install.sh",
+ "name": "php-apt",
+ "title": "PHP[APT]",
+ "coexist": true,
+ "versions": ["74","80","81","82"],
+ "install_pre_inspection":true,
+ "tip": "soft",
+ "checks": "server/php-apt/VERSION",
+ "path": "server/php-apt/VERSION",
+ "display": 1,
+ "author": "Zend",
+ "date": "2022-07-07",
+ "home": "https://www.php.net",
+ "type": "PHP语言解释器",
+ "pid": "1"
+}
\ No newline at end of file
diff --git a/plugins/php-apt/install.sh b/plugins/php-apt/install.sh
new file mode 100755
index 000000000..5f0adafc9
--- /dev/null
+++ b/plugins/php-apt/install.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
+export PATH
+
+curPath=`pwd`
+rootPath=$(dirname "$curPath")
+rootPath=$(dirname "$rootPath")
+serverPath=$(dirname "$rootPath")
+
+install_tmp=${rootPath}/tmp/mw_install.pl
+
+if id www &> /dev/null ;then
+ echo "www UID is `id -u www`"
+ echo "www Shell is `grep "^www:" /etc/passwd |cut -d':' -f7 `"
+else
+ groupadd www
+ # useradd -g www -s /sbin/nologin www
+ useradd -g www -s /bin/bash www
+fi
+
+action=$1
+type=$2
+
+if [ "${2}" == "" ];then
+ echo '缺少安装脚本...' > $install_tmp
+ exit 0
+fi
+
+if [ ! -d $curPath/versions/$2 ];then
+ echo '缺少安装脚本2...' > $install_tmp
+ exit 0
+fi
+
+
+if [ "${action}" == "uninstall" ] && [ -d ${serverPath}/php-apt/${type} ];then
+ #初始化
+ cd ${rootPath} && python3 ${rootPath}/plugins/php-apt/index.py stop ${type}
+ cd ${rootPath} && python3 ${rootPath}/plugins/php-apt/index.py initd_uninstall ${type}
+fi
+
+cd ${curPath} && sh -x $curPath/versions/$2/install.sh $1
+
+if [ "${action}" == "install" ] && [ -d ${serverPath}/php-apt/${type} ];then
+ #初始化
+ cd ${rootPath} && python3 ${rootPath}/plugins/php-apt/index.py start ${type}
+ cd ${rootPath} && python3 ${rootPath}/plugins/php-apt/index.py initd_install ${type}
+fi
+
+
diff --git a/plugins/php-apt/js/php.js b/plugins/php-apt/js/php.js
new file mode 100755
index 000000000..b4fea5398
--- /dev/null
+++ b/plugins/php-apt/js/php.js
@@ -0,0 +1,545 @@
+
+function str2Obj(str){
+ var data = {};
+ kv = str.split('&');
+ for(i in kv){
+ v = kv[i].split('=');
+ data[v[0]] = v[1];
+ }
+ return data;
+}
+
+function phpPost(method, version, args,callback){
+ var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
+
+ var req_data = {};
+ req_data['name'] = 'php-apt';
+ req_data['func'] = method;
+ req_data['version'] = version;
+
+ if (typeof(args) == 'string'){
+ req_data['args'] = JSON.stringify(str2Obj(args));
+ } else {
+ req_data['args'] = JSON.stringify(args);
+ }
+
+ $.post('/plugins/run', req_data, function(data) {
+ layer.close(loadT);
+ if (!data.status){
+ //错误展示10S
+ layer.msg(data.msg,{icon:0,time:2000,shade: [10, '#000']});
+ return;
+ }
+
+ if(typeof(callback) == 'function'){
+ callback(data);
+ }
+ },'json');
+}
+
+function phpPostCallbak(method, version, args,callback){
+ var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
+
+ var req_data = {};
+ req_data['name'] = 'php-apt';
+ req_data['func'] = method;
+ args['version'] = version;
+
+ if (typeof(args) == 'string'){
+ req_data['args'] = JSON.stringify(str2Obj(args));
+ } else {
+ req_data['args'] = JSON.stringify(args);
+ }
+
+ $.post('/plugins/callback', req_data, function(data) {
+ layer.close(loadT);
+ if (!data.status){
+ layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
+ return;
+ }
+
+ if(typeof(callback) == 'function'){
+ callback(data);
+ }
+ },'json');
+}
+
+
+//配置修改
+function phpSetConfig(version) {
+ phpPost('get_php_conf', version,'',function(data){
+ // console.log(data);
+ var rdata = $.parseJSON(data.data);
+ // console.log(rdata);
+ var mlist = '';
+ for (var i = 0; i < rdata.length; i++) {
+ var w = '70'
+ if (rdata[i].name == 'error_reporting') w = '250';
+ var ibody = '';
+ switch (rdata[i].type) {
+ case 0:
+ var selected_1 = (rdata[i].value == 1) ? 'selected' : '';
+ var selected_0 = (rdata[i].value == 0) ? 'selected' : '';
+ ibody = ''
+ break;
+ case 1:
+ var selected_1 = (rdata[i].value == 'On') ? 'selected' : '';
+ var selected_0 = (rdata[i].value == 'Off') ? 'selected' : '';
+ ibody = ''
+ break;
+ }
+ mlist += '' + rdata[i].name + '' + ibody + ', ' + rdata[i].ps + '
'
+ }
+ var phpCon = '\
+ ' + mlist + '\
+
\
+
'
+ $(".soft-man-con").html(phpCon);
+ });
+}
+
+
+//提交PHP配置
+function submitConf(version) {
+ var data = {
+ version: version,
+ display_errors: $("select[name='display_errors']").val(),
+ 'cgi.fix_pathinfo': $("select[name='cgi.fix_pathinfo']").val(),
+ 'date.timezone': $("input[name='date.timezone']").val(),
+ short_open_tag: $("select[name='short_open_tag']").val(),
+ asp_tags: $("select[name='asp_tags']").val() || 'On',
+ safe_mode: $("select[name='safe_mode']").val(),
+ max_execution_time: $("input[name='max_execution_time']").val(),
+ max_input_time: $("input[name='max_input_time']").val(),
+ max_input_vars: $("input[name='max_input_vars']").val(),
+ memory_limit: $("input[name='memory_limit']").val(),
+ post_max_size: $("input[name='post_max_size']").val(),
+ file_uploads: $("select[name='file_uploads']").val(),
+ upload_max_filesize: $("input[name='upload_max_filesize']").val(),
+ max_file_uploads: $("input[name='max_file_uploads']").val(),
+ default_socket_timeout: $("input[name='default_socket_timeout']").val(),
+ error_reporting: $("input[name='error_reporting']").val() || 'On'
+ };
+
+ phpPost('submit_php_conf', version, data, function(ret_data){
+ var rdata = $.parseJSON(ret_data.data);
+ // console.log(rdata);
+ layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
+ });
+}
+
+
+
+//php上传限制
+function phpUploadLimitReq(version){
+ phpPost('get_limit_conf', version, '', function(ret_data){
+ var rdata = $.parseJSON(ret_data.data);
+ phpUploadLimit(version,rdata['max']);
+ });
+}
+
+function phpUploadLimit(version,max){
+ var LimitCon = 'MB
';
+ $(".soft-man-con").html(LimitCon);
+}
+
+
+//php超时限制
+function phpTimeLimitReq(version){
+ phpPost('get_limit_conf', version, '', function(ret_data){
+ var rdata = $.parseJSON(ret_data.data);
+ phpTimeLimit(version,rdata['maxTime']);
+ });
+}
+
+function phpTimeLimit(version, max) {
+ var LimitCon = '秒
';
+ $(".soft-man-con").html(LimitCon);
+}
+
+//设置超时限制
+function setPHPMaxTime(version) {
+ var max = $(".phpTimeLimit").val();
+ phpPost('set_max_time',version,{'time':max},function(data){
+ var rdata = $.parseJSON(data.data);
+ layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
+ });
+}
+//设置PHP上传限制
+function setPHPMaxSize(version) {
+ max = $(".phpUploadLimit").val();
+ if (max < 2) {
+ alert(max);
+ layer.msg('上传大小限制不能小于2M', { icon: 2 });
+ return;
+ }
+
+ phpPost('set_max_size',version,{'max':max},function(data){
+ var rdata = $.parseJSON(data.data);
+ layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
+ });
+}
+
+
+function getFpmConfig(version){
+ phpPost('get_fpm_conf', version, {}, function(data){
+ // console.log(data);
+ var rdata = $.parseJSON(data.data);
+ // console.log(rdata);
+ var limitList = "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ ""
+ var pms = [{ 'name': 'static', 'title': '静态' }, { 'name': 'dynamic', 'title': '动态' }];
+ var pmList = '';
+ for (var i = 0; i < pms.length; i++) {
+ pmList += '';
+ }
+ var body = "" +
+ "
并发方案:
" +
+ "
运行模式:*PHP-FPM运行模式
" +
+ "
max_children:*允许创建的最大子进程数
" +
+ "
start_servers: *起始进程数(服务启动后初始进程数量)
" +
+ "
min_spare_servers: *最小空闲进程数(清理空闲进程后的保留数量)
" +
+ "
max_spare_servers: *最大空闲进程数(当空闲进程达到此值时清理)
" +
+ "
" +
+ "
";
+
+ $(".soft-man-con").html(body);
+ $("select[name='limit']").change(function() {
+ var type = $(this).val();
+ var max_children = rdata.max_children;
+ var start_servers = rdata.start_servers;
+ var min_spare_servers = rdata.min_spare_servers;
+ var max_spare_servers = rdata.max_spare_servers;
+ switch (type) {
+ case '1':
+ max_children = 30;
+ start_servers = 5;
+ min_spare_servers = 5;
+ max_spare_servers = 20;
+ break;
+ case '2':
+ max_children = 50;
+ start_servers = 15;
+ min_spare_servers = 15;
+ max_spare_servers = 35;
+ break;
+ case '3':
+ max_children = 100;
+ start_servers = 20;
+ min_spare_servers = 20;
+ max_spare_servers = 70;
+ break;
+ case '4':
+ max_children = 200;
+ start_servers = 25;
+ min_spare_servers = 25;
+ max_spare_servers = 150;
+ break;
+ case '5':
+ max_children = 300;
+ start_servers = 30;
+ min_spare_servers = 30;
+ max_spare_servers = 180;
+ break;
+ case '6':
+ max_children = 500;
+ start_servers = 35;
+ min_spare_servers = 35;
+ max_spare_servers = 250;
+ break;
+ }
+
+ $("input[name='max_children']").val(max_children);
+ $("input[name='start_servers']").val(start_servers);
+ $("input[name='min_spare_servers']").val(min_spare_servers);
+ $("input[name='max_spare_servers']").val(max_spare_servers);
+ });
+ });
+}
+
+function setFpmConfig(version){
+ var max_children = Number($("input[name='max_children']").val());
+ var start_servers = Number($("input[name='start_servers']").val());
+ var min_spare_servers = Number($("input[name='min_spare_servers']").val());
+ var max_spare_servers = Number($("input[name='max_spare_servers']").val());
+ var pm = $("select[name='pm']").val();
+
+ if (max_children < max_spare_servers) {
+ layer.msg('max_spare_servers 不能大于 max_children', { icon: 2 });
+ return;
+ }
+
+ if (min_spare_servers > start_servers) {
+ layer.msg('min_spare_servers 不能大于 start_servers', { icon: 2 });
+ return;
+ }
+
+ if (max_spare_servers < min_spare_servers) {
+ layer.msg('min_spare_servers 不能大于 max_spare_servers', { icon: 2 });
+ return;
+ }
+
+ if (max_children < start_servers) {
+ layer.msg('start_servers 不能大于 max_children', { icon: 2 });
+ return;
+ }
+
+ if (max_children < 1 || start_servers < 1 || min_spare_servers < 1 || max_spare_servers < 1) {
+ layer.msg('配置值不能小于1', { icon: 2 });
+ return;
+ }
+
+ var data = {
+ version:version,
+ max_children:max_children,
+ start_servers:start_servers,
+ min_spare_servers:min_spare_servers,
+ max_spare_servers:max_spare_servers,
+ pm:pm,
+ };
+ phpPost('set_fpm_conf', version, data, function(ret_data){
+ var rdata = $.parseJSON(ret_data.data);
+ layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
+ });
+}
+
+
+function getFpmStatus(version){
+ phpPost('get_fpm_status', version, '', function(ret_data){
+ var tmp_data = $.parseJSON(ret_data.data);
+ if(!tmp_data.status){
+ layer.msg(tmp_data.msg, { icon: tmp_data.status ? 1 : 2 });
+ return;
+ }
+
+ var rdata = tmp_data.data;
+ var con = "\
+ 应用池(pool) | " + rdata.pool + " |
\
+ 进程管理方式(process manager) | " + ((rdata['process manager'] == 'dynamic') ? '动态' : '静态') + " |
\
+ 启动日期(start time) | " + rdata['start time'] + " |
\
+ 请求数(accepted conn) | " + rdata['accepted conn'] + " |
\
+ 请求队列(listen queue) | " + rdata['listen queue'] + " |
\
+ 最大等待队列(max listen queue) | " + rdata['max listen queue'] + " |
\
+ socket队列长度(listen queue len) | " + rdata['listen queue len'] + " |
\
+ 空闲进程数量(idle processes) | " + rdata['idle processes'] + " |
\
+ 活跃进程数量(active processes) | " + rdata['active processes'] + " |
\
+ 总进程数量(total processes) | " + rdata['total processes'] + " |
\
+ 最大活跃进程数量(max active processes) | " + rdata['max active processes'] + " |
\
+ 到达进程上限次数(max children reached) | " + rdata['max children reached'] + " |
\
+ 慢请求数量(slow requests) | " + rdata['slow requests'] + " |
\
+
";
+ $(".soft-man-con").html(con);
+ $(".GetPHPStatus td,.GetPHPStatus th").css("padding", "7px");
+ });
+}
+
+//禁用函数
+function disableFunc(version) {
+ phpPost('get_disable_func', version,'',function(data){
+ var rdata = $.parseJSON(data.data);
+ var disable_functions = rdata.disable_functions.split(',');
+ var dbody = ''
+ for (var i = 0; i < disable_functions.length; i++) {
+ if (disable_functions[i] == '') continue;
+ dbody += "" + disable_functions[i] + " | 删除 |
";
+ }
+
+ var con = "" +
+ "" +
+ "" +
+ "
" +
+ "" +
+ "名称 | 操作 |
" +
+ "" + dbody + "" +
+ "
";
+
+ con += '\
+ - 在此处可以禁用指定函数的调用,以增强环境安全性!
\
+ - 强烈建议禁用如exec,system等危险函数!
\
+
';
+
+ $(".soft-man-con").html(con);
+ });
+}
+//设置禁用函数
+function setDisableFunc(version, act, fs) {
+ var fsArr = fs.split(',');
+ if (act == 1) {
+ var functions = $("#disable_function_val").val();
+ for (var i = 0; i < fsArr.length; i++) {
+ if (functions == fsArr[i]) {
+ layer.msg(lan.soft.fun_msg, { icon: 5 });
+ return;
+ }
+ }
+ fs += ',' + functions;
+ msg = '添加成功';
+ } else {
+
+ fs = '';
+ for (var i = 0; i < fsArr.length; i++) {
+ if (act == fsArr[i]) continue;
+ fs += fsArr[i] + ','
+ }
+ msg = '删除成功';
+ fs = fs.substr(0, fs.length - 1);
+ }
+
+ var data = {
+ 'version':version,
+ 'disable_functions':fs,
+ };
+
+ phpPost('set_disable_func', version,data,function(data){
+ var rdata = $.parseJSON(data.data);
+ showMsg(rdata.status ? msg : rdata.msg, function(){
+ disableFunc(version);
+ } ,{ icon: rdata.status ? 1 : 2 });
+ });
+}
+
+
+//phpinfo
+function getPhpinfo(version) {
+ var con = '';
+ $(".soft-man-con").html(con);
+}
+
+//获取PHPInfo
+function getPHPInfo_old(version) {
+ phpPost('get_phpinfo', version, '', function(data){
+ var rdata = data.data;
+ layer.open({
+ type: 1,
+ title: "PHP-" + version + "-PHPINFO",
+ area: ['90%', '90%'],
+ closeBtn: 2,
+ shadeClose: true,
+ content: rdata
+ });
+ });
+}
+
+function getPHPInfo(version) {
+ phpPostCallbak('get_php_info', version, {}, function(data){
+ if (!data.status){
+ layer.msg(rdata.msg, { icon: 2 });
+ }
+
+ layer.open({
+ type: 1,
+ title: "PHP-" + version + "-PHPINFO",
+ area: ['90%', '90%'],
+ closeBtn: 2,
+ shadeClose: true,
+ content: data.data
+ });
+ })
+}
+
+
+function phpLibConfig(version){
+
+ phpPost('get_lib_conf', version, '', function(data){
+ var rdata = $.parseJSON(data.data);
+
+ if (!rdata.status){
+ layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
+ return;
+ }
+
+ var libs = rdata.data;
+ var body = '';
+ var opt = '';
+
+ for (var i = 0; i < libs.length; i++) {
+ if (libs[i].versions.indexOf(version) == -1){
+ continue;
+ }
+
+ if (libs[i]['task'] == '-1' && libs[i].phpversions.indexOf(version) != -1) {
+ opt = '安装'
+ } else if (libs[i]['task'] == '0' && libs[i].phpversions.indexOf(version) != -1) {
+ opt = '等待安装...'
+ } else if (libs[i].status) {
+ opt = '卸载'
+ } else {
+ opt = '安装'
+ }
+
+ body += '' +
+ '' + libs[i].name + ' | ' +
+ '' + libs[i].type + ' | ' +
+ '' + libs[i].msg + ' | ' +
+ ' | ' +
+ '' + opt + ' | ' +
+ '
';
+ }
+
+
+ var con = '' +
+ '
' +
+ '' +
+ '' +
+ '名称 | ' +
+ '类型 | ' +
+ '说明 | ' +
+ '状态 | ' +
+ '操作 | ' +
+ '
' +
+ '' +
+ '' + body + '' +
+ '
' +
+ '
' +
+ '\
+ - 请按实际需求安装扩展,不要安装不必要的PHP扩展,这会影响PHP执行效率,甚至出现异常
\
+ - Redis扩展只允许在1个PHP版本中使用,安装到其它PHP版本请在[软件管理]重装Redis
\
+ - opcache/xcache/apc等脚本缓存扩展,请只安装其中1个,否则可能导致您的站点程序异常
\
+ - ioncube要在ZendGuardLoader/opcache前安装,否则可能导致您的站点程序异常
\
+
';
+ $('.soft-man-con').html(con);
+ });
+
+}
+
+//安装扩展
+function installPHPLib(version, name, title, pathinfo) {
+ layer.confirm('您真的要安装{1}吗?'.replace('{1}', name), { icon: 3, closeBtn: 2 }, function() {
+ name = name.toLowerCase();
+ var data = "name=" + name + "&version=" + version + "&type=1";
+
+ phpPost('install_lib', version, data, function(data){
+ var rdata = $.parseJSON(data.data);
+ // layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
+ showMsg(rdata.msg, function(){
+ getTaskCount();
+ phpLibConfig(version);
+ },{ icon: rdata.status ? 1 : 2 });
+
+ });
+ });
+}
+
+//卸载扩展
+function uninstallPHPLib(version, name, title, pathinfo) {
+ layer.confirm('您真的要安装{1}吗?'.replace('{1}', name), { icon: 3, closeBtn: 2 }, function() {
+ name = name.toLowerCase();
+ var data = 'name=' + name + '&version=' + version;
+ phpPost('uninstall_lib', version, data, function(data){
+ var rdata = $.parseJSON(data.data);
+ // layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
+ showMsg(rdata.msg, function(){
+ getTaskCount();
+ phpLibConfig(version);
+ },{ icon: rdata.status ? 1 : 2 },5000);
+
+ });
+ });
+}
\ No newline at end of file
diff --git a/plugins/php-apt/versions/74/install.sh b/plugins/php-apt/versions/74/install.sh
new file mode 100755
index 000000000..ef8f50566
--- /dev/null
+++ b/plugins/php-apt/versions/74/install.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
+export PATH
+
+curPath=`pwd`
+rootPath=$(dirname "$curPath")
+rootPath=$(dirname "$rootPath")
+serverPath=$(dirname "$rootPath")
+sourcePath=${serverPath}/source
+sysName=`uname`
+install_tmp=${rootPath}/tmp/mw_install.pl
+
+
+#获取信息和版本
+# bash /www/server/mdsever-web/scripts/getos.sh
+bash ${rootPath}/scripts/getos.sh
+OSNAME=`cat ${rootPath}/data/osname.pl`
+VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
+
+version=7.4.x
+PHP_VER=74
+
+
+Install_php()
+{
+#------------------------ install start ------------------------------------#
+
+### centos start ################
+rpm -Uvh http://rpms.remirepo.net/enterprise/remi-release-${VERSION_ID}.rpm
+yum install -y php74 php74-php-fpm
+### centos start ################
+
+if [ "$?" == "0" ];then
+ mkdir -p $serverPath/php-yum/${PHP_VER}
+fi
+
+#------------------------ install end ------------------------------------#
+}
+
+Uninstall_php()
+{
+ # $serverPath/php-ya/init.d/php${PHP_VER} stop
+ rm -rf $serverPath/php-yum/${PHP_VER}
+ echo "卸载php-${version}..." > $install_tmp
+}
+
+action=${1}
+if [ "${1}" == 'install' ];then
+ Install_php
+else
+ Uninstall_php
+fi
diff --git a/plugins/php-apt/versions/80/install.sh b/plugins/php-apt/versions/80/install.sh
new file mode 100755
index 000000000..99361224b
--- /dev/null
+++ b/plugins/php-apt/versions/80/install.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
+export PATH
+
+curPath=`pwd`
+rootPath=$(dirname "$curPath")
+rootPath=$(dirname "$rootPath")
+serverPath=$(dirname "$rootPath")
+sourcePath=${serverPath}/source
+sysName=`uname`
+install_tmp=${rootPath}/tmp/mw_install.pl
+
+
+#获取信息和版本
+# bash /www/server/mdsever-web/scripts/getos.sh
+bash ${rootPath}/scripts/getos.sh
+OSNAME=`cat ${rootPath}/data/osname.pl`
+VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
+
+version=8.0.x
+PHP_VER=80
+
+
+Install_php()
+{
+#------------------------ install start ------------------------------------#
+
+### centos start ################
+rpm -Uvh http://rpms.remirepo.net/enterprise/remi-release-${VERSION_ID}.rpm
+yum install -y php80 php80-php-fpm
+### centos start ################
+
+if [ "$?" == "0" ];then
+ mkdir -p $serverPath/php-yum/${PHP_VER}
+fi
+
+#------------------------ install end ------------------------------------#
+}
+
+Uninstall_php()
+{
+ # $serverPath/php-ya/init.d/php${PHP_VER} stop
+ rm -rf $serverPath/php-yum/${PHP_VER}
+ echo "卸载php-${version}..." > $install_tmp
+}
+
+action=${1}
+if [ "${1}" == 'install' ];then
+ Install_php
+else
+ Uninstall_php
+fi
diff --git a/plugins/php-apt/versions/81/install.sh b/plugins/php-apt/versions/81/install.sh
new file mode 100755
index 000000000..f60ec2b71
--- /dev/null
+++ b/plugins/php-apt/versions/81/install.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
+export PATH
+
+curPath=`pwd`
+rootPath=$(dirname "$curPath")
+rootPath=$(dirname "$rootPath")
+serverPath=$(dirname "$rootPath")
+sourcePath=${serverPath}/source
+sysName=`uname`
+install_tmp=${rootPath}/tmp/mw_install.pl
+
+
+#获取信息和版本
+# bash /www/server/mdsever-web/scripts/getos.sh
+bash ${rootPath}/scripts/getos.sh
+OSNAME=`cat ${rootPath}/data/osname.pl`
+VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
+
+version=8.1.x
+PHP_VER=81
+
+
+Install_php()
+{
+#------------------------ install start ------------------------------------#
+
+### centos start ################
+rpm -Uvh http://rpms.remirepo.net/enterprise/remi-release-${VERSION_ID}.rpm
+yum install -y php81 php81-php-fpm
+### centos start ################
+
+if [ "$?" == "0" ];then
+ mkdir -p $serverPath/php-yum/${PHP_VER}
+fi
+
+#------------------------ install end ------------------------------------#
+}
+
+Uninstall_php()
+{
+ # $serverPath/php-ya/init.d/php${PHP_VER} stop
+ rm -rf $serverPath/php-yum/${PHP_VER}
+ echo "卸载php-${version}..." > $install_tmp
+}
+
+action=${1}
+if [ "${1}" == 'install' ];then
+ Install_php
+else
+ Uninstall_php
+fi
diff --git a/plugins/php-apt/versions/82/install.sh b/plugins/php-apt/versions/82/install.sh
new file mode 100755
index 000000000..15cac2de7
--- /dev/null
+++ b/plugins/php-apt/versions/82/install.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
+export PATH
+
+curPath=`pwd`
+rootPath=$(dirname "$curPath")
+rootPath=$(dirname "$rootPath")
+serverPath=$(dirname "$rootPath")
+sourcePath=${serverPath}/source
+sysName=`uname`
+install_tmp=${rootPath}/tmp/mw_install.pl
+
+
+#获取信息和版本
+# bash /www/server/mdsever-web/scripts/getos.sh
+bash ${rootPath}/scripts/getos.sh
+OSNAME=`cat ${rootPath}/data/osname.pl`
+VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
+
+version=8.2.x
+PHP_VER=82
+
+
+Install_php()
+{
+#------------------------ install start ------------------------------------#
+
+### centos start ################
+rpm -Uvh http://rpms.remirepo.net/enterprise/remi-release-${VERSION_ID}.rpm
+yum install -y php82 php82-php-fpm
+### centos start ################
+
+if [ "$?" == "0" ];then
+ mkdir -p $serverPath/php-apt/${PHP_VER}
+fi
+
+#------------------------ install end ------------------------------------#
+}
+
+Uninstall_php()
+{
+ # $serverPath/php-ya/init.d/php${PHP_VER} stop
+ rm -rf $serverPath/php-apt/${PHP_VER}
+ echo "卸载php-${version}..." > $install_tmp
+}
+
+action=${1}
+if [ "${1}" == 'install' ];then
+ Install_php
+else
+ Uninstall_php
+fi
diff --git a/plugins/php-apt/versions/common.sh b/plugins/php-apt/versions/common.sh
new file mode 100644
index 000000000..038a1fe07
--- /dev/null
+++ b/plugins/php-apt/versions/common.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
+export PATH
+
+curPath=`pwd`
+rootPath=$(dirname "$curPath")
+rootPath=$(dirname "$rootPath")
+rootPath=$(dirname "$rootPath")
+serverPath=$(dirname "$rootPath")
+
+version=$1
+action=$2
+extName=$3
+
+# echo $1,$2,$3
+
+# echo $curPath
+# echo $rootPath
+# echo $serverPath
+
+FILE=${curPath}/${version}/${extName}.sh
+
+# yum install -y php81-php-yar
+
+
+if [ "$action" == 'install' ];then
+
+ if [ -f $FILE ];then
+ bash ${curPath}/${version}/${extName}.sh install
+ else
+ yum install -y php${version}-php*-${extName}
+ fi
+fi
+
+
+# yum remove -y php81-php-yar
+if [ "$action" == 'uninstall' ];then
+
+ if [ -f $FILE ];then
+ bash ${curPath}/${version}/${extName}.sh uninstall
+ else
+ yum remove -y php${version}-php*-${extName}
+ fi
+fi
+
+echo "yum install -y php${version}-php-${extName}"
+echo "yum remove -y php${version}-php-${extName}"
+
+
+
diff --git a/plugins/php-apt/versions/lib.sh b/plugins/php-apt/versions/lib.sh
new file mode 100644
index 000000000..5702d47ed
--- /dev/null
+++ b/plugins/php-apt/versions/lib.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
+export PATH
+
+curPath=`pwd`
+rootPath=$(dirname "$curPath")
+rootPath=$(dirname "$rootPath")
+rootPath=$(dirname "$rootPath")
+serverPath=$(dirname "$rootPath")
+
+version=$1
+action=$2
+
+if [ -f /lib/systemd/system/php${version}.service ];then
+ systemctl ${action} php${version}
+elif [[ -f /usr/lib/systemd/system/php${version}.service ]]; then
+ systemctl ${action} php${version}
+else
+ $serverPath/php/init.d/php${version} ${action}
+fi
\ No newline at end of file
diff --git a/plugins/php-apt/versions/phplib.conf b/plugins/php-apt/versions/phplib.conf
new file mode 100755
index 000000000..1599e6217
--- /dev/null
+++ b/plugins/php-apt/versions/phplib.conf
@@ -0,0 +1,534 @@
+[
+ {
+ "name": "pdo",
+ "versions": [
+ "74",
+ "80",
+ "81",
+ "82"
+ ],
+ "type": "数据库",
+ "msg": "数据库访问抽象模块!",
+ "shell": "pdo.sh",
+ "check": "pdo"
+ },
+ {
+ "name": "mysqlnd",
+ "versions": [
+ "53",
+ "54",
+ "56",
+ "80",
+ "81",
+ "82"
+ ],
+ "type": "数据库",
+ "msg": "用于使用MySQL数据库的模块!",
+ "shell": "mysqlnd.sh",
+ "check": "mysqlnd"
+ },
+ {
+ "name": "oci8",
+ "versions": [
+ "53",
+ "54",
+ "56",
+ "80",
+ "81",
+ "82"
+ ],
+ "type": "数据库",
+ "msg": "用于使用OCI8数据库的模块!",
+ "shell": "oci8.sh",
+ "check": "oci8"
+ },
+ {
+ "name": "odbc",
+ "versions": [
+ "53",
+ "54",
+ "56",
+ "80",
+ "81",
+ "82"
+ ],
+ "type": "数据库",
+ "msg": "用于使用ODBC数据库的模块!",
+ "shell": "odbc.sh",
+ "check": "odbc"
+ },
+ {
+ "name": "ZendGuardLoader",
+ "versions": [
+ "53",
+ "54",
+ "56"
+ ],
+ "type": "脚本解密",
+ "msg": "用于解密ZendGuard加密脚本!",
+ "shell": "zend_guard_loader.sh",
+ "check": "ZendGuardLoader"
+ },
+ {
+ "name": "ZendOptimizer",
+ "versions": [
+ "52"
+ ],
+ "type": "脚本解密",
+ "msg": "用于解密ZendOptimizer加密脚本!",
+ "shell": "zend_optimizer.sh",
+ "check": "ZendOptimizer"
+ },
+ {
+ "name": "ionCube",
+ "versions": [
+ "52",
+ "53",
+ "54",
+ "55",
+ "56",
+ "70",
+ "71",
+ "72",
+ "73",
+ "74"
+ ],
+ "type": "脚本解密",
+ "msg": "用于解密ionCube Encoder加密脚本!",
+ "shell": "ioncube.sh",
+ "check": "ioncube"
+ },
+ {
+ "name": "opcache",
+ "versions": [
+ "53",
+ "54",
+ "55",
+ "56",
+ "70",
+ "71",
+ "72",
+ "73",
+ "74",
+ "80",
+ "81",
+ "82"
+ ],
+ "type": "缓存器",
+ "msg": "用于加速PHP脚本!",
+ "shell": "opcache.sh",
+ "check": "opcache"
+ },
+ {
+ "name": "mcrypt",
+ "versions": [
+ "71",
+ "72",
+ "73",
+ "74",
+ "80",
+ "81"
+ ],
+ "type": "通用扩展",
+ "msg": "加密软件!",
+ "shell": "mcrypt.sh",
+ "check": "mcrypt"
+ },
+ {
+ "name": "fileinfo",
+ "versions": [
+ "53",
+ "54",
+ "55",
+ "56",
+ "70",
+ "71",
+ "72",
+ "73",
+ "74",
+ "80",
+ "81"
+ ],
+ "type": "通用扩展",
+ "msg": "用于FILE!",
+ "shell": "fileinfo.sh",
+ "check": "fileinfo"
+ },
+ {
+ "name": "exif",
+ "versions": [
+ "53",
+ "54",
+ "55",
+ "56",
+ "70",
+ "71",
+ "72",
+ "73",
+ "74",
+ "80",
+ "81"
+ ],
+ "type": "通用扩展",
+ "msg": "用于图像文件格式!",
+ "shell": "exif.sh",
+ "check": "exif"
+ },
+ {
+ "name": "gd",
+ "versions": [
+ "74",
+ "80",
+ "81",
+ "82"
+ ],
+ "type": "通用扩展",
+ "msg": "通用GD库!",
+ "shell": "gd.sh",
+ "check": "gd"
+ },
+ {
+ "name": "intl",
+ "versions": [
+ "52",
+ "53",
+ "54",
+ "55",
+ "56",
+ "70",
+ "71",
+ "72",
+ "73",
+ "74",
+ "80",
+ "81",
+ "82"
+ ],
+ "type": "通用扩展",
+ "msg": "提供国际化支持",
+ "shell": "intl.sh",
+ "check": "intl"
+ },
+ {
+ "name": "memcache",
+ "versions": [
+ "74",
+ "80",
+ "81"
+ ],
+ "type": "缓存器",
+ "msg": "强大的内容缓存器,不支持集群",
+ "shell": "memcache.sh",
+ "check": "memcache"
+ },
+ {
+ "name": "memcached",
+ "versions": [
+ "53",
+ "54",
+ "55",
+ "56",
+ "70",
+ "71",
+ "72",
+ "73",
+ "74",
+ "80",
+ "81",
+ "82"
+ ],
+ "type": "缓存器",
+ "msg": "强大的内容缓存器,支持集群",
+ "shell": "memcached.sh",
+ "check": "memcached"
+ },
+ {
+ "name": "redis",
+ "versions": [
+ "52",
+ "53",
+ "54",
+ "55",
+ "56",
+ "70",
+ "71",
+ "72",
+ "73",
+ "74",
+ "80",
+ "81"
+ ],
+ "type": "缓存器",
+ "msg": "更强大的内容缓存器,支持集群",
+ "shell": "redis.sh",
+ "check": "redis"
+ },
+ {
+ "name": "apc",
+ "versions": [
+ "53",
+ "54"
+ ],
+ "type": "缓存器",
+ "msg": "脚本缓存器",
+ "shell": "apc.sh",
+ "check": "apc"
+ },
+ {
+ "name": "imagick-im7",
+ "versions": [
+ "54",
+ "55",
+ "56",
+ "70",
+ "71",
+ "72",
+ "73",
+ "74",
+ "80",
+ "81",
+ "82"
+ ],
+ "type": "通用扩展",
+ "msg": "比GD更强大的图形库",
+ "shell": "imagick.sh",
+ "check": "imagick"
+ },
+ {
+ "name": "xdebug",
+ "versions": [
+ "53",
+ "54",
+ "55",
+ "56",
+ "70",
+ "71",
+ "72",
+ "73",
+ "74",
+ "80",
+ "81"
+ ],
+ "type": "调试器",
+ "msg": "不多说,不了解的不要安装",
+ "shell": "xdebug.sh",
+ "check": "xdebug"
+ },
+ {
+ "name": "xhprof",
+ "versions": [
+ "52",
+ "53",
+ "54",
+ "55",
+ "56",
+ "70",
+ "71",
+ "72",
+ "73",
+ "74",
+ "80",
+ "81"
+ ],
+ "type": "性能分析",
+ "msg": "不多说,不了解的不要安装!",
+ "shell": "xhprof.sh",
+ "check": "xhprof"
+ },
+ {
+ "name": "Swoole",
+ "versions": [
+ "53",
+ "54",
+ "55",
+ "56",
+ "70",
+ "71",
+ "72",
+ "73",
+ "74",
+ "80",
+ "81"
+ ],
+ "type": "通用扩展",
+ "msg": "异步、并行、高性能网络通信引擎",
+ "shell": "swoole.sh",
+ "check": "swoole"
+ },
+ {
+ "name": "eAccelerator",
+ "versions": [
+ "52",
+ "53"
+ ],
+ "type": "缓存器",
+ "msg": "内容缓存器",
+ "shell": "eaccelerator.sh",
+ "check": "eaccelerator"
+ },
+ {
+ "name": "yaf",
+ "versions": [
+ "53",
+ "54",
+ "55",
+ "56",
+ "70",
+ "71",
+ "72",
+ "73",
+ "74",
+ "80",
+ "81"
+ ],
+ "type": "框架",
+ "msg": "Yaf是一个C语言编写的PHP框架",
+ "shell": "yaf.sh",
+ "check": "yaf"
+ },
+ {
+ "name": "yar",
+ "versions": [
+ "53",
+ "54",
+ "55",
+ "56",
+ "70",
+ "71",
+ "72",
+ "73",
+ "74",
+ "80",
+ "81"
+ ],
+ "type": "框架",
+ "msg": "Yar是一个RPC框架",
+ "shell": "yar.sh",
+ "check": "yar"
+ },
+ {
+ "name": "mongo",
+ "versions": [
+ "53",
+ "54",
+ "55",
+ "56"
+ ],
+ "type": "通用扩展",
+ "msg": "Mongodb数据库连接驱动",
+ "shell": "mongo.sh",
+ "check": "mongo"
+ },
+ {
+ "name": "mongodb",
+ "versions": [
+ "55",
+ "56",
+ "70",
+ "71",
+ "72",
+ "73",
+ "74",
+ "80",
+ "81"
+ ],
+ "type": "通用扩展",
+ "msg": "Mongodb数据库连接驱动",
+ "shell": "mongodb.sh",
+ "check": "mongodb"
+ },
+ {
+ "name": "yac",
+ "versions": [
+ "70",
+ "71",
+ "72",
+ "73",
+ "74",
+ "80",
+ "81"
+ ],
+ "type": "缓存器",
+ "msg": "高性能无锁共享内存Cache",
+ "shell": "yac.sh",
+ "check": "yac"
+ },
+ {
+ "name": "solr",
+ "versions": [
+ "53",
+ "54",
+ "55",
+ "56",
+ "70",
+ "71",
+ "72",
+ "73",
+ "74",
+ "80",
+ "81"
+ ],
+ "type": "大数据",
+ "msg": "SOLR全文搜索服务",
+ "shell": "solr.sh",
+ "check": "solr"
+ },
+ {
+ "name": "seaslog",
+ "versions": [
+ "53",
+ "54",
+ "55",
+ "56",
+ "70",
+ "71",
+ "72",
+ "73",
+ "74",
+ "80",
+ "81"
+ ],
+ "type": "日志",
+ "msg": "SeasLog高性能日志记录",
+ "shell": "seaslog.sh",
+ "check": "seaslog"
+ },
+ {
+ "name": "mbstring",
+ "versions": [
+ "53",
+ "54",
+ "55",
+ "56",
+ "70",
+ "71",
+ "72",
+ "73",
+ "74",
+ "80",
+ "81",
+ "82"
+ ],
+ "type": "通用扩展",
+ "msg": "用于需要多字节字符串处理的模块",
+ "shell": "mbstring.sh",
+ "check": "mbstring"
+ },
+ {
+ "name": "zip",
+ "versions": [
+ "70",
+ "71",
+ "72",
+ "73",
+ "74",
+ "80",
+ "81",
+ "82"
+ ],
+ "type": "压缩",
+ "msg": "压缩组件",
+ "shell": "zip.sh",
+ "check": "zip"
+ }
+]
\ No newline at end of file