2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-04 22:07:16 +08:00

feat: add php 81 82

This commit is contained in:
耗子
2023-07-27 00:57:13 +08:00
parent ecaf8edf14
commit 2ed5c36890
8 changed files with 1587 additions and 1 deletions

View File

@@ -0,0 +1,371 @@
package php81
import (
"fmt"
"regexp"
"strings"
"time"
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/facades"
"github.com/imroc/req/v3"
"panel/app/http/controllers"
"panel/app/models"
"panel/app/services"
"panel/pkg/tools"
)
type Php81Controller struct {
setting services.Setting
task services.Task
version string
}
func NewPhp81Controller() *Php81Controller {
return &Php81Controller{
setting: services.NewSettingImpl(),
task: services.NewTaskImpl(),
version: "81",
}
}
func (c *Php81Controller) Status(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
status := tools.ExecShell("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
if len(status) == 0 {
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
return
}
if status == "active" {
controllers.Success(ctx, true)
} else {
controllers.Success(ctx, false)
}
}
func (c *Php81Controller) Reload(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
tools.ExecShell("systemctl reload php-fpm-" + c.version)
out := tools.ExecShell("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
status := strings.TrimSpace(out)
if len(status) == 0 {
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
return
}
if status == "active" {
controllers.Success(ctx, true)
} else {
controllers.Success(ctx, false)
}
}
func (c *Php81Controller) Start(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
tools.ExecShell("systemctl start php-fpm-" + c.version)
out := tools.ExecShell("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
status := strings.TrimSpace(out)
if len(status) == 0 {
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
return
}
if status == "active" {
controllers.Success(ctx, true)
} else {
controllers.Success(ctx, false)
}
}
func (c *Php81Controller) Stop(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
tools.ExecShell("systemctl stop php-fpm-" + c.version)
out := tools.ExecShell("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
status := strings.TrimSpace(out)
if len(status) == 0 {
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
return
}
if status != "active" {
controllers.Success(ctx, true)
} else {
controllers.Success(ctx, false)
}
}
func (c *Php81Controller) Restart(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
tools.ExecShell("systemctl restart php-fpm-" + c.version)
out := tools.ExecShell("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
status := strings.TrimSpace(out)
if len(status) == 0 {
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
return
}
if status == "active" {
controllers.Success(ctx, true)
} else {
controllers.Success(ctx, false)
}
}
func (c *Php81Controller) GetConfig(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
config := tools.ReadFile("/www/server/php/" + c.version + "/etc/php.ini")
controllers.Success(ctx, config)
}
func (c *Php81Controller) SaveConfig(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
config := ctx.Request().Input("config")
tools.WriteFile("/www/server/php/"+c.version+"/etc/php.ini", config, 0644)
c.Reload(ctx)
}
func (c *Php81Controller) Load(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
client := req.C().SetTimeout(10 * time.Second)
resp, err := client.R().Get("http://127.0.0.1/phpfpm_status/" + c.version)
if err != nil || !resp.IsSuccessState() {
facades.Log().Error("获取PHP-" + c.version + "运行状态失败")
controllers.Error(ctx, http.StatusInternalServerError, "[PHP-"+c.version+"] 获取运行状态失败")
return
}
raw := resp.String()
dataKeys := []string{"应用池", "工作模式", "启动时间", "接受连接", "监听队列", "最大监听队列", "监听队列长度", "空闲进程数量", "活动进程数量", "总进程数量", "最大活跃进程数量", "达到进程上限次数", "慢请求"}
regexKeys := []string{"pool", "process manager", "start time", "accepted conn", "listen queue", "max listen queue", "listen queue len", "idle processes", "active processes", "total processes", "max active processes", "max children reached", "slow requests"}
type Data struct {
Name string `json:"name"`
Value string `json:"value"`
}
data := make([]Data, len(dataKeys))
for i := range dataKeys {
data[i].Name = dataKeys[i]
r := regexp.MustCompile(fmt.Sprintf("%s:\\s+(.*)", regexKeys[i]))
match := r.FindStringSubmatch(raw)
if len(match) > 1 {
data[i].Value = strings.TrimSpace(match[1])
}
}
controllers.Success(ctx, data)
}
func (c *Php81Controller) ErrorLog(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
log := tools.ExecShell("tail -n 100 /www/server/php/" + c.version + "/var/log/php-fpm.log")
controllers.Success(ctx, log)
}
func (c *Php81Controller) SlowLog(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
log := tools.ExecShell("tail -n 100 /www/server/php/" + c.version + "/var/log/slow.log")
controllers.Success(ctx, log)
}
func (c *Php81Controller) ClearErrorLog(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
tools.ExecShell("echo '' > /www/server/php/" + c.version + "/var/log/php-fpm.log")
controllers.Success(ctx, true)
}
func (c *Php81Controller) ClearSlowLog(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
tools.ExecShell("echo '' > /www/server/php/" + c.version + "/var/log/slow.log")
controllers.Success(ctx, true)
}
type Extension struct {
Name string `json:"name"`
Slug string `json:"slug"`
Description string `json:"description"`
Installed bool `json:"installed"`
}
func (c *Php81Controller) GetExtensionList(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
extensions := c.GetExtensions()
controllers.Success(ctx, extensions)
}
func (c *Php81Controller) InstallExtension(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
slug := ctx.Request().Input("slug")
if len(slug) == 0 {
controllers.Error(ctx, http.StatusBadRequest, "参数错误")
return
}
extensions := c.GetExtensions()
for _, item := range extensions {
if item.Slug == slug {
if item.Installed {
controllers.Error(ctx, http.StatusBadRequest, "扩展已安装")
return
}
var task models.Task
task.Name = "安装PHP-" + c.version + "扩展-" + item.Name
task.Status = models.TaskStatusWaiting
task.Shell = `bash '/www/panel/scripts/php_extensions/` + item.Slug + `.sh' install ` + c.version + ` >> /tmp/` + item.Slug + `.log 2>&1`
task.Log = "/tmp/" + item.Slug + ".log"
if err := facades.Orm().Query().Create(&task); err != nil {
facades.Log().Error("[PHP-" + c.version + "] 创建安装拓展任务失败:" + err.Error())
controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
return
}
c.task.Process(task.ID)
controllers.Success(ctx, true)
return
}
}
controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
}
func (c *Php81Controller) UninstallExtension(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
slug := ctx.Request().Input("slug")
if len(slug) == 0 {
controllers.Error(ctx, http.StatusBadRequest, "参数错误")
return
}
extensions := c.GetExtensions()
for _, item := range extensions {
if item.Slug == slug {
if !item.Installed {
controllers.Error(ctx, http.StatusBadRequest, "扩展未安装")
return
}
var task models.Task
task.Name = "卸载PHP-" + c.version + "扩展-" + item.Name
task.Status = models.TaskStatusWaiting
task.Shell = `bash '/www/panel/scripts/php_extensions/` + item.Slug + `.sh' uninstall ` + c.version + ` >> /tmp/` + item.Slug + `.log 2>&1`
task.Log = "/tmp/" + item.Slug + ".log"
if err := facades.Orm().Query().Create(&task); err != nil {
facades.Log().Error("[PHP-" + c.version + "] 创建卸载拓展任务失败:" + err.Error())
controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
return
}
c.task.Process(task.ID)
controllers.Success(ctx, true)
return
}
}
controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
}
func (c *Php81Controller) GetExtensions() []Extension {
var extensions []Extension
extensions = append(extensions, Extension{
Name: "OPcache",
Slug: "Zend OPcache",
Description: "OPcache 通过将 PHP 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能,存储预编译字节码可以省去每次加载和解析 PHP 脚本的开销。",
Installed: false,
})
extensions = append(extensions, Extension{
Name: "PhpRedis",
Slug: "redis",
Description: "PhpRedis 是一个用C语言编写的PHP模块用来连接并操作 Redis 数据库上的数据。",
Installed: false,
})
extensions = append(extensions, Extension{
Name: "ImageMagick",
Slug: "imagick",
Description: "ImageMagick 是一个免费的创建、编辑、合成图片的软件。",
Installed: false,
})
extensions = append(extensions, Extension{
Name: "Exif",
Slug: "exif",
Description: "通过 exif 扩展,你可以操作图像元数据。",
Installed: false,
})
extensions = append(extensions, Extension{
Name: "pdo_pgsql",
Slug: "pdo_pgsql",
Description: "需先安装PostgreSQLpdo_pgsql 是一个驱动程序,它实现了 PHP 数据对象PDO接口以启用从 PHP 到 PostgreSQL 数据库的访问。",
Installed: false,
})
extensions = append(extensions, Extension{
Name: "ionCube",
Slug: "ionCube Loader",
Description: "ionCube 是一个专业级的PHP加密解密工具。",
Installed: false,
})
raw := tools.ExecShell("/www/server/php/" + c.version + "/bin/php -m")
rawExtensionList := strings.Split(raw, "\n")
for _, item := range rawExtensionList {
if !strings.Contains(item, "[") && item != "" {
for i := range extensions {
if extensions[i].Slug == item {
extensions[i].Installed = true
}
}
}
}
return extensions
}

View File

@@ -0,0 +1,365 @@
package php82
import (
"fmt"
"regexp"
"strings"
"time"
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/facades"
"github.com/imroc/req/v3"
"panel/app/http/controllers"
"panel/app/models"
"panel/app/services"
"panel/pkg/tools"
)
type Php82Controller struct {
setting services.Setting
task services.Task
version string
}
func NewPhp82Controller() *Php82Controller {
return &Php82Controller{
setting: services.NewSettingImpl(),
task: services.NewTaskImpl(),
version: "82",
}
}
func (c *Php82Controller) Status(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
status := tools.ExecShell("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
if len(status) == 0 {
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
return
}
if status == "active" {
controllers.Success(ctx, true)
} else {
controllers.Success(ctx, false)
}
}
func (c *Php82Controller) Reload(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
tools.ExecShell("systemctl reload php-fpm-" + c.version)
out := tools.ExecShell("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
status := strings.TrimSpace(out)
if len(status) == 0 {
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
return
}
if status == "active" {
controllers.Success(ctx, true)
} else {
controllers.Success(ctx, false)
}
}
func (c *Php82Controller) Start(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
tools.ExecShell("systemctl start php-fpm-" + c.version)
out := tools.ExecShell("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
status := strings.TrimSpace(out)
if len(status) == 0 {
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
return
}
if status == "active" {
controllers.Success(ctx, true)
} else {
controllers.Success(ctx, false)
}
}
func (c *Php82Controller) Stop(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
tools.ExecShell("systemctl stop php-fpm-" + c.version)
out := tools.ExecShell("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
status := strings.TrimSpace(out)
if len(status) == 0 {
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
return
}
if status != "active" {
controllers.Success(ctx, true)
} else {
controllers.Success(ctx, false)
}
}
func (c *Php82Controller) Restart(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
tools.ExecShell("systemctl restart php-fpm-" + c.version)
out := tools.ExecShell("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
status := strings.TrimSpace(out)
if len(status) == 0 {
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
return
}
if status == "active" {
controllers.Success(ctx, true)
} else {
controllers.Success(ctx, false)
}
}
func (c *Php82Controller) GetConfig(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
config := tools.ReadFile("/www/server/php/" + c.version + "/etc/php.ini")
controllers.Success(ctx, config)
}
func (c *Php82Controller) SaveConfig(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
config := ctx.Request().Input("config")
tools.WriteFile("/www/server/php/"+c.version+"/etc/php.ini", config, 0644)
c.Reload(ctx)
}
func (c *Php82Controller) Load(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
client := req.C().SetTimeout(10 * time.Second)
resp, err := client.R().Get("http://127.0.0.1/phpfpm_status/" + c.version)
if err != nil || !resp.IsSuccessState() {
facades.Log().Error("获取PHP-" + c.version + "运行状态失败")
controllers.Error(ctx, http.StatusInternalServerError, "[PHP-"+c.version+"] 获取运行状态失败")
return
}
raw := resp.String()
dataKeys := []string{"应用池", "工作模式", "启动时间", "接受连接", "监听队列", "最大监听队列", "监听队列长度", "空闲进程数量", "活动进程数量", "总进程数量", "最大活跃进程数量", "达到进程上限次数", "慢请求"}
regexKeys := []string{"pool", "process manager", "start time", "accepted conn", "listen queue", "max listen queue", "listen queue len", "idle processes", "active processes", "total processes", "max active processes", "max children reached", "slow requests"}
type Data struct {
Name string `json:"name"`
Value string `json:"value"`
}
data := make([]Data, len(dataKeys))
for i := range dataKeys {
data[i].Name = dataKeys[i]
r := regexp.MustCompile(fmt.Sprintf("%s:\\s+(.*)", regexKeys[i]))
match := r.FindStringSubmatch(raw)
if len(match) > 1 {
data[i].Value = strings.TrimSpace(match[1])
}
}
controllers.Success(ctx, data)
}
func (c *Php82Controller) ErrorLog(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
log := tools.ExecShell("tail -n 100 /www/server/php/" + c.version + "/var/log/php-fpm.log")
controllers.Success(ctx, log)
}
func (c *Php82Controller) SlowLog(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
log := tools.ExecShell("tail -n 100 /www/server/php/" + c.version + "/var/log/slow.log")
controllers.Success(ctx, log)
}
func (c *Php82Controller) ClearErrorLog(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
tools.ExecShell("echo '' > /www/server/php/" + c.version + "/var/log/php-fpm.log")
controllers.Success(ctx, true)
}
func (c *Php82Controller) ClearSlowLog(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
tools.ExecShell("echo '' > /www/server/php/" + c.version + "/var/log/slow.log")
controllers.Success(ctx, true)
}
type Extension struct {
Name string `json:"name"`
Slug string `json:"slug"`
Description string `json:"description"`
Installed bool `json:"installed"`
}
func (c *Php82Controller) GetExtensionList(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
extensions := c.GetExtensions()
controllers.Success(ctx, extensions)
}
func (c *Php82Controller) InstallExtension(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
slug := ctx.Request().Input("slug")
if len(slug) == 0 {
controllers.Error(ctx, http.StatusBadRequest, "参数错误")
return
}
extensions := c.GetExtensions()
for _, item := range extensions {
if item.Slug == slug {
if item.Installed {
controllers.Error(ctx, http.StatusBadRequest, "扩展已安装")
return
}
var task models.Task
task.Name = "安装PHP-" + c.version + "扩展-" + item.Name
task.Status = models.TaskStatusWaiting
task.Shell = `bash '/www/panel/scripts/php_extensions/` + item.Slug + `.sh' install ` + c.version + ` >> /tmp/` + item.Slug + `.log 2>&1`
task.Log = "/tmp/" + item.Slug + ".log"
if err := facades.Orm().Query().Create(&task); err != nil {
facades.Log().Error("[PHP-" + c.version + "] 创建安装拓展任务失败:" + err.Error())
controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
return
}
c.task.Process(task.ID)
controllers.Success(ctx, true)
return
}
}
controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
}
func (c *Php82Controller) UninstallExtension(ctx http.Context) {
if !controllers.Check(ctx, "php"+c.version) {
return
}
slug := ctx.Request().Input("slug")
if len(slug) == 0 {
controllers.Error(ctx, http.StatusBadRequest, "参数错误")
return
}
extensions := c.GetExtensions()
for _, item := range extensions {
if item.Slug == slug {
if !item.Installed {
controllers.Error(ctx, http.StatusBadRequest, "扩展未安装")
return
}
var task models.Task
task.Name = "卸载PHP-" + c.version + "扩展-" + item.Name
task.Status = models.TaskStatusWaiting
task.Shell = `bash '/www/panel/scripts/php_extensions/` + item.Slug + `.sh' uninstall ` + c.version + ` >> /tmp/` + item.Slug + `.log 2>&1`
task.Log = "/tmp/" + item.Slug + ".log"
if err := facades.Orm().Query().Create(&task); err != nil {
facades.Log().Error("[PHP-" + c.version + "] 创建卸载拓展任务失败:" + err.Error())
controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
return
}
c.task.Process(task.ID)
controllers.Success(ctx, true)
return
}
}
controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
}
func (c *Php82Controller) GetExtensions() []Extension {
var extensions []Extension
extensions = append(extensions, Extension{
Name: "OPcache",
Slug: "Zend OPcache",
Description: "OPcache 通过将 PHP 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能,存储预编译字节码可以省去每次加载和解析 PHP 脚本的开销。",
Installed: false,
})
extensions = append(extensions, Extension{
Name: "PhpRedis",
Slug: "redis",
Description: "PhpRedis 是一个用C语言编写的PHP模块用来连接并操作 Redis 数据库上的数据。",
Installed: false,
})
extensions = append(extensions, Extension{
Name: "ImageMagick",
Slug: "imagick",
Description: "ImageMagick 是一个免费的创建、编辑、合成图片的软件。",
Installed: false,
})
extensions = append(extensions, Extension{
Name: "Exif",
Slug: "exif",
Description: "通过 exif 扩展,你可以操作图像元数据。",
Installed: false,
})
extensions = append(extensions, Extension{
Name: "pdo_pgsql",
Slug: "pdo_pgsql",
Description: "需先安装PostgreSQLpdo_pgsql 是一个驱动程序,它实现了 PHP 数据对象PDO接口以启用从 PHP 到 PostgreSQL 数据库的访问。",
Installed: false,
})
raw := tools.ExecShell("/www/server/php/" + c.version + "/bin/php -m")
rawExtensionList := strings.Split(raw, "\n")
for _, item := range rawExtensionList {
if !strings.Contains(item, "[") && item != "" {
for i := range extensions {
if extensions[i].Slug == item {
extensions[i].Installed = true
}
}
}
}
return extensions
}

View File

@@ -0,0 +1,13 @@
package php81
var (
Name = "PHP-8.1"
Description = "PHP 是世界上最好的语言!"
Slug = "php81"
Version = "8.1.21"
Requires = []string{}
Excludes = []string{}
Install = `bash /www/panel/scripts/php/install.sh 81`
Uninstall = `bash /www/panel/scripts/php/uninstall.sh 81`
Update = `bash /www/panel/scripts/php/install.sh 81`
)

View File

@@ -0,0 +1,13 @@
package php82
var (
Name = "PHP-8.2"
Description = "PHP 是世界上最好的语言!"
Slug = "php82"
Version = "8.2.8"
Requires = []string{}
Excludes = []string{}
Install = `bash /www/panel/scripts/php/install.sh 82`
Uninstall = `bash /www/panel/scripts/php/uninstall.sh 82`
Update = `bash /www/panel/scripts/php/install.sh 82`
)

View File

@@ -10,6 +10,8 @@ import (
"panel/app/plugins/openresty"
"panel/app/plugins/php74"
"panel/app/plugins/php80"
"panel/app/plugins/php81"
"panel/app/plugins/php82"
"panel/app/plugins/phpmyadmin"
"panel/app/plugins/s3fs"
"panel/app/plugins/supervisor"
@@ -111,6 +113,28 @@ func (r *PluginImpl) All() []PanelPlugin {
Uninstall: php80.Uninstall,
Update: php80.Update,
})
p = append(p, PanelPlugin{
Name: php81.Name,
Description: php81.Description,
Slug: php81.Slug,
Version: php81.Version,
Requires: php81.Requires,
Excludes: php81.Excludes,
Install: php81.Install,
Uninstall: php81.Uninstall,
Update: php81.Update,
})
p = append(p, PanelPlugin{
Name: php82.Name,
Description: php82.Description,
Slug: php82.Slug,
Version: php82.Version,
Requires: php82.Requires,
Excludes: php82.Excludes,
Install: php82.Install,
Uninstall: php82.Uninstall,
Update: php82.Update,
})
p = append(p, PanelPlugin{
Name: phpmyadmin.Name,
Description: phpmyadmin.Description,

View File

@@ -0,0 +1,381 @@
<!--
Name: PHP管理器
Author: 耗子
Date: 2023-07-22
-->
<title>PHP-8.1</title>
<div class="layui-fluid" id="component-tabs">
<div class="layui-row">
<div class="layui-col-md12">
<div class="layui-card">
<div class="layui-card-header">PHP-8.1管理</div>
<div class="layui-card-body">
<div class="layui-tab">
<ul class="layui-tab-title">
<li class="layui-this">运行状态</li>
<li>拓展管理</li>
<li>配置修改</li>
<li>负载状态</li>
<li>运行日志</li>
<li>慢日志</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<blockquote id="php81-status" class="layui-elem-quote layui-quote-nm">当前状态:<span
class="layui-badge layui-bg-black">获取中</span></blockquote>
<div class="layui-btn-container" style="padding-top: 30px;">
<button id="php81-start" class="layui-btn">启动</button>
<button id="php81-stop" class="layui-btn layui-btn-danger">停止</button>
<button id="php81-restart" class="layui-btn layui-btn-warm">重启</button>
<button id="php81-reload" class="layui-btn layui-btn-normal">重载</button>
</div>
</div>
<div class="layui-tab-item">
<table id="php81-extension" lay-filter="php81-extension"></table>
<!-- 操作按钮模板 -->
<script type="text/html" id="php81-extension-control">
{{# if(d.installed == true){ }}
<a class="layui-btn layui-btn-warm layui-btn-xs" lay-event="uninstall">卸载</a>
{{# } else{ }}
<a class="layui-btn layui-btn-xs" lay-event="install">安装</a>
{{# } }}
</script>
</div>
<div class="layui-tab-item">
<blockquote class="layui-elem-quote">此处修改的是PHP主配置文件如果你不了解各参数的含义请不要随意修改<br>
提示Ctrl+F 搜索关键字Ctrl+S 保存Ctrl+H 查找替换!
</blockquote>
<div id="php81-config-editor"
style="height: 600px;"></div>
<div class="layui-btn-container" style="padding-top: 30px;">
<button id="php81-config-save" class="layui-btn">保存</button>
</div>
</div>
<div class="layui-tab-item">
<table class="layui-hide" id="php81-load-status"></table>
</div>
<div class="layui-tab-item">
<div class="layui-btn-container">
<button id="php81-clean-error-log" class="layui-btn">清空日志</button>
</div>
<pre id="php81-error-log" class="layui-code">
获取中...
</pre>
</div>
<div class="layui-tab-item">
<div class="layui-btn-container">
<button id="php81-clean-slow-log" class="layui-btn">清空日志</button>
</div>
<pre id="php81-slow-log" class="layui-code">
获取中...
</pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
let php81_config_editor;
layui.use(['index', 'code', 'table'], function () {
let $ = layui.$
, admin = layui.admin
, element = layui.element
, code = layui.code
, table = layui.table;
// 获取php81运行状态并渲染
admin.req({
url: "/api/plugins/php81/status"
, type: 'get'
, success: function (result) {
if (result.code !== 0) {
console.log('耗子Linux面板PHP运行状态获取失败接口返回' + result);
return false;
}
if (result.data) {
$('#php81-status').html('当前状态:<span class="layui-badge layui-bg-green">运行中</span>');
} else {
$('#php81-status').html('当前状态:<span class="layui-badge layui-bg-red">已停止</span>');
}
}
});
// 获取php81错误日志并渲染
admin.req({
url: "/api/plugins/php81/errorLog"
, type: 'get'
, success: function (result) {
if (result.code !== 0) {
$('#php81-error-log').text('PHP日志获取失败请刷新重试');
code({
elem: '#php81-error-log'
, title: 'php-fpm.log'
, encode: true
, about: false
});
return false;
}
$('#php81-error-log').text(result.data);
code({
elem: '#php81-error-log'
, title: 'php-fpm.log'
, encode: true
, about: false
});
}
});
// 获取php81慢日志并渲染
admin.req({
url: "/api/plugins/php81/slowLog"
, type: 'get'
, success: function (result) {
if (result.code !== 0) {
$('#php81-slow-log').text('PHP慢日志获取失败请刷新重试');
code({
elem: '#php81-slow-log'
, title: 'slow.log'
, encode: true
, about: false
});
return false;
}
$('#php81-slow-log').text(result.data);
code({
elem: '#php81-slow-log'
, title: 'slow.log'
, encode: true
, about: false
});
}
});
// 获取php81配置并渲染
admin.req({
url: "/api/plugins/php81/config"
, type: 'get'
, success: function (result) {
if (result.code !== 0) {
console.log('耗子Linux面板PHP主配置获取失败接口返回' + result);
return false;
}
$('#php81-config-editor').text(result.data);
php81_config_editor = ace.edit("php81-config-editor", {
mode: "ace/mode/ini",
selectionStyle: "text"
});
}
});
// 获取php81负载状态并渲染
table.render({
elem: '#php81-load-status'
, url: '/api/plugins/php81/load'
, cols: [[
{field: 'name', width: '81%', title: '属性',}
, {field: 'value', width: '20%', title: '当前值'}
]]
});
element.render();
// 获取php81扩展并渲染
table.render({
elem: '#php81-extension'
, url: '/api/plugins/php81/extensions'
, cols: [[
{field: 'slug', hide: true, title: 'Slug', sort: true}
, {field: 'name', width: '20%', title: '拓展名'}
, {field: 'description', width: '70%', title: '描述'}
, {
field: 'control',
title: '操作',
templet: '#php81-extension-control',
fixed: 'right',
align: 'left'
}
]]
, page: false
, text: {
none: '暂无拓展'
}
});
// 工具条
table.on('tool(php81-extension)', function (obj) {
let data = obj.data;
if (obj.event === 'install') {
layer.confirm('确定安装该拓展吗?', function (index) {
layer.close(index);
index = layer.msg('请稍后...', {icon: 16, time: 0});
admin.req({
url: '/api/plugins/php81/installExtension',
type: 'POST',
data: {
slug: data.slug
}
, success: function (res) {
if (res.code === 0) {
layer.close(index);
table.reload('php81-extension');
layer.msg('安装:' + data.name + ' 成功加入任务队列', {
icon: 1,
time: 1000
});
} else {
layer.msg(res.msg, {icon: 2, time: 1000});
}
}
});
});
} else if (obj.event === 'uninstall') {
layer.confirm('确定卸载该拓展吗?', function (index) {
layer.close(index);
index = layer.msg('请稍后...', {icon: 16, time: 0});
admin.req({
url: '/api/plugins/php81/uninstallExtension',
type: 'POST',
data: {
slug: data.slug
}
, success: function (res) {
layer.close(index);
if (res.code === 0) {
table.reload('php81-extension');
layer.msg('卸载:' + data.name + ' 成功加入任务队列', {icon: 1, time: 1000});
} else {
layer.msg(res.msg, {icon: 2, time: 1000});
}
}
});
});
}
});
// 事件监听
$('#php81-start').click(function () {
index = layer.msg('正在启动PHP请稍后...', {icon: 16, time: 0});
layer.confirm('确定要启动PHP吗', {
btn: ['启动', '取消']
}, function () {
admin.req({
url: "/api/plugins/php81/start"
, type: 'post'
, success: function (result) {
layer.close(index);
if (result.code !== 0) {
return false;
}
admin.events.refresh();
layer.alert('PHP启动成功');
}
});
});
});
$('#php81-stop').click(function () {
layer.confirm('停止PHP将导致使用PHP的网站无法访问是否继续停止', {
btn: ['停止', '取消']
}, function () {
index = layer.msg('正在停止PHP请稍后...', {icon: 16, time: 0});
admin.req({
url: "/api/plugins/php81/stop"
, type: 'post'
, success: function (result) {
layer.close(index);
if (result.code !== 0) {
return false;
}
admin.events.refresh();
layer.alert('PHP停止成功');
}
});
});
});
$('#php81-restart').click(function () {
layer.confirm('重启PHP将导致使用PHP的网站短时间无法访问是否继续重启', {
btn: ['重启', '取消']
}, function () {
index = layer.msg('正在重启PHP请稍后...', {icon: 16, time: 0});
admin.req({
url: "/api/plugins/php81/restart"
, type: 'post'
, success: function (result) {
layer.close(index);
if (result.code !== 0) {
return false;
}
admin.events.refresh();
layer.alert('PHP重启成功');
}
});
});
});
$('#php81-reload').click(function () {
index = layer.msg('正在重载PHP请稍后...', {icon: 16, time: 0});
admin.req({
url: "/api/plugins/php81/reload"
, type: 'post'
, success: function (result) {
layer.close(index);
if (result.code !== 0) {
return false;
}
layer.alert('PHP重载成功');
}
});
});
$('#php81-config-save').click(function () {
index = layer.msg('正在保存配置,请稍后...', {icon: 16, time: 0});
admin.req({
url: "/api/plugins/php81/config"
, type: 'post'
, data: {
config: php81_config_editor.getValue()
}
, success: function (result) {
layer.close(index);
if (result.code !== 0) {
return false;
}
layer.alert('PHP配置保存成功');
}
});
});
$('#php81-clean-error-log').click(function () {
index = layer.msg('正在清空错误日志,请稍后...', {icon: 16, time: 0});
admin.req({
url: "/api/plugins/php81/clearErrorLog"
, type: 'post'
, success: function (result) {
layer.close(index);
if (result.code !== 0) {
return false;
}
admin.events.refresh();
layer.msg('PHP日志已清空');
}
});
});
$('#php81-clean-slow-log').click(function () {
index = layer.msg('正在清空慢日志,请稍后...', {icon: 16, time: 0});
admin.req({
url: "/api/plugins/php81/clearSlowLog"
, type: 'post'
, success: function (result) {
if (result.code !== 0) {
return false;
}
admin.events.refresh();
layer.msg('PHP慢日志已清空');
}
});
});
});
</script>

View File

@@ -0,0 +1,381 @@
<!--
Name: PHP管理器
Author: 耗子
Date: 2023-07-22
-->
<title>PHP-8.2</title>
<div class="layui-fluid" id="component-tabs">
<div class="layui-row">
<div class="layui-col-md12">
<div class="layui-card">
<div class="layui-card-header">PHP-8.2管理</div>
<div class="layui-card-body">
<div class="layui-tab">
<ul class="layui-tab-title">
<li class="layui-this">运行状态</li>
<li>拓展管理</li>
<li>配置修改</li>
<li>负载状态</li>
<li>运行日志</li>
<li>慢日志</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<blockquote id="php82-status" class="layui-elem-quote layui-quote-nm">当前状态:<span
class="layui-badge layui-bg-black">获取中</span></blockquote>
<div class="layui-btn-container" style="padding-top: 30px;">
<button id="php82-start" class="layui-btn">启动</button>
<button id="php82-stop" class="layui-btn layui-btn-danger">停止</button>
<button id="php82-restart" class="layui-btn layui-btn-warm">重启</button>
<button id="php82-reload" class="layui-btn layui-btn-normal">重载</button>
</div>
</div>
<div class="layui-tab-item">
<table id="php82-extension" lay-filter="php82-extension"></table>
<!-- 操作按钮模板 -->
<script type="text/html" id="php82-extension-control">
{{# if(d.installed == true){ }}
<a class="layui-btn layui-btn-warm layui-btn-xs" lay-event="uninstall">卸载</a>
{{# } else{ }}
<a class="layui-btn layui-btn-xs" lay-event="install">安装</a>
{{# } }}
</script>
</div>
<div class="layui-tab-item">
<blockquote class="layui-elem-quote">此处修改的是PHP主配置文件如果你不了解各参数的含义请不要随意修改<br>
提示Ctrl+F 搜索关键字Ctrl+S 保存Ctrl+H 查找替换!
</blockquote>
<div id="php82-config-editor"
style="height: 600px;"></div>
<div class="layui-btn-container" style="padding-top: 30px;">
<button id="php82-config-save" class="layui-btn">保存</button>
</div>
</div>
<div class="layui-tab-item">
<table class="layui-hide" id="php82-load-status"></table>
</div>
<div class="layui-tab-item">
<div class="layui-btn-container">
<button id="php82-clean-error-log" class="layui-btn">清空日志</button>
</div>
<pre id="php82-error-log" class="layui-code">
获取中...
</pre>
</div>
<div class="layui-tab-item">
<div class="layui-btn-container">
<button id="php82-clean-slow-log" class="layui-btn">清空日志</button>
</div>
<pre id="php82-slow-log" class="layui-code">
获取中...
</pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
let php82_config_editor;
layui.use(['index', 'code', 'table'], function () {
let $ = layui.$
, admin = layui.admin
, element = layui.element
, code = layui.code
, table = layui.table;
// 获取php82运行状态并渲染
admin.req({
url: "/api/plugins/php82/status"
, type: 'get'
, success: function (result) {
if (result.code !== 0) {
console.log('耗子Linux面板PHP运行状态获取失败接口返回' + result);
return false;
}
if (result.data) {
$('#php82-status').html('当前状态:<span class="layui-badge layui-bg-green">运行中</span>');
} else {
$('#php82-status').html('当前状态:<span class="layui-badge layui-bg-red">已停止</span>');
}
}
});
// 获取php82错误日志并渲染
admin.req({
url: "/api/plugins/php82/errorLog"
, type: 'get'
, success: function (result) {
if (result.code !== 0) {
$('#php82-error-log').text('PHP日志获取失败请刷新重试');
code({
elem: '#php82-error-log'
, title: 'php-fpm.log'
, encode: true
, about: false
});
return false;
}
$('#php82-error-log').text(result.data);
code({
elem: '#php82-error-log'
, title: 'php-fpm.log'
, encode: true
, about: false
});
}
});
// 获取php82慢日志并渲染
admin.req({
url: "/api/plugins/php82/slowLog"
, type: 'get'
, success: function (result) {
if (result.code !== 0) {
$('#php82-slow-log').text('PHP慢日志获取失败请刷新重试');
code({
elem: '#php82-slow-log'
, title: 'slow.log'
, encode: true
, about: false
});
return false;
}
$('#php82-slow-log').text(result.data);
code({
elem: '#php82-slow-log'
, title: 'slow.log'
, encode: true
, about: false
});
}
});
// 获取php82配置并渲染
admin.req({
url: "/api/plugins/php82/config"
, type: 'get'
, success: function (result) {
if (result.code !== 0) {
console.log('耗子Linux面板PHP主配置获取失败接口返回' + result);
return false;
}
$('#php82-config-editor').text(result.data);
php82_config_editor = ace.edit("php82-config-editor", {
mode: "ace/mode/ini",
selectionStyle: "text"
});
}
});
// 获取php82负载状态并渲染
table.render({
elem: '#php82-load-status'
, url: '/api/plugins/php82/load'
, cols: [[
{field: 'name', width: '82%', title: '属性',}
, {field: 'value', width: '20%', title: '当前值'}
]]
});
element.render();
// 获取php82扩展并渲染
table.render({
elem: '#php82-extension'
, url: '/api/plugins/php82/extensions'
, cols: [[
{field: 'slug', hide: true, title: 'Slug', sort: true}
, {field: 'name', width: '20%', title: '拓展名'}
, {field: 'description', width: '70%', title: '描述'}
, {
field: 'control',
title: '操作',
templet: '#php82-extension-control',
fixed: 'right',
align: 'left'
}
]]
, page: false
, text: {
none: '暂无拓展'
}
});
// 工具条
table.on('tool(php82-extension)', function (obj) {
let data = obj.data;
if (obj.event === 'install') {
layer.confirm('确定安装该拓展吗?', function (index) {
layer.close(index);
index = layer.msg('请稍后...', {icon: 16, time: 0});
admin.req({
url: '/api/plugins/php82/installExtension',
type: 'POST',
data: {
slug: data.slug
}
, success: function (res) {
if (res.code === 0) {
layer.close(index);
table.reload('php82-extension');
layer.msg('安装:' + data.name + ' 成功加入任务队列', {
icon: 1,
time: 1000
});
} else {
layer.msg(res.msg, {icon: 2, time: 1000});
}
}
});
});
} else if (obj.event === 'uninstall') {
layer.confirm('确定卸载该拓展吗?', function (index) {
layer.close(index);
index = layer.msg('请稍后...', {icon: 16, time: 0});
admin.req({
url: '/api/plugins/php82/uninstallExtension',
type: 'POST',
data: {
slug: data.slug
}
, success: function (res) {
layer.close(index);
if (res.code === 0) {
table.reload('php82-extension');
layer.msg('卸载:' + data.name + ' 成功加入任务队列', {icon: 1, time: 1000});
} else {
layer.msg(res.msg, {icon: 2, time: 1000});
}
}
});
});
}
});
// 事件监听
$('#php82-start').click(function () {
index = layer.msg('正在启动PHP请稍后...', {icon: 16, time: 0});
layer.confirm('确定要启动PHP吗', {
btn: ['启动', '取消']
}, function () {
admin.req({
url: "/api/plugins/php82/start"
, type: 'post'
, success: function (result) {
layer.close(index);
if (result.code !== 0) {
return false;
}
admin.events.refresh();
layer.alert('PHP启动成功');
}
});
});
});
$('#php82-stop').click(function () {
layer.confirm('停止PHP将导致使用PHP的网站无法访问是否继续停止', {
btn: ['停止', '取消']
}, function () {
index = layer.msg('正在停止PHP请稍后...', {icon: 16, time: 0});
admin.req({
url: "/api/plugins/php82/stop"
, type: 'post'
, success: function (result) {
layer.close(index);
if (result.code !== 0) {
return false;
}
admin.events.refresh();
layer.alert('PHP停止成功');
}
});
});
});
$('#php82-restart').click(function () {
layer.confirm('重启PHP将导致使用PHP的网站短时间无法访问是否继续重启', {
btn: ['重启', '取消']
}, function () {
index = layer.msg('正在重启PHP请稍后...', {icon: 16, time: 0});
admin.req({
url: "/api/plugins/php82/restart"
, type: 'post'
, success: function (result) {
layer.close(index);
if (result.code !== 0) {
return false;
}
admin.events.refresh();
layer.alert('PHP重启成功');
}
});
});
});
$('#php82-reload').click(function () {
index = layer.msg('正在重载PHP请稍后...', {icon: 16, time: 0});
admin.req({
url: "/api/plugins/php82/reload"
, type: 'post'
, success: function (result) {
layer.close(index);
if (result.code !== 0) {
return false;
}
layer.alert('PHP重载成功');
}
});
});
$('#php82-config-save').click(function () {
index = layer.msg('正在保存配置,请稍后...', {icon: 16, time: 0});
admin.req({
url: "/api/plugins/php82/config"
, type: 'post'
, data: {
config: php82_config_editor.getValue()
}
, success: function (result) {
layer.close(index);
if (result.code !== 0) {
return false;
}
layer.alert('PHP配置保存成功');
}
});
});
$('#php82-clean-error-log').click(function () {
index = layer.msg('正在清空错误日志,请稍后...', {icon: 16, time: 0});
admin.req({
url: "/api/plugins/php82/clearErrorLog"
, type: 'post'
, success: function (result) {
layer.close(index);
if (result.code !== 0) {
return false;
}
admin.events.refresh();
layer.msg('PHP日志已清空');
}
});
});
$('#php82-clean-slow-log').click(function () {
index = layer.msg('正在清空慢日志,请稍后...', {icon: 16, time: 0});
admin.req({
url: "/api/plugins/php82/clearSlowLog"
, type: 'post'
, success: function (result) {
if (result.code !== 0) {
return false;
}
admin.events.refresh();
layer.msg('PHP慢日志已清空');
}
});
});
});
</script>

View File

@@ -3,15 +3,17 @@ package routes
import (
"github.com/goravel/framework/contracts/route"
"github.com/goravel/framework/facades"
"panel/app/http/controllers/plugins/supervisor"
"panel/app/http/controllers/plugins/mysql57"
"panel/app/http/controllers/plugins/mysql80"
"panel/app/http/controllers/plugins/openresty"
"panel/app/http/controllers/plugins/php74"
"panel/app/http/controllers/plugins/php80"
"panel/app/http/controllers/plugins/php81"
"panel/app/http/controllers/plugins/php82"
"panel/app/http/controllers/plugins/phpmyadmin"
"panel/app/http/controllers/plugins/s3fs"
"panel/app/http/controllers/plugins/supervisor"
"panel/app/http/middleware"
)
@@ -126,6 +128,42 @@ func Plugin() {
route.Post("installExtension", php80Controller.InstallExtension)
route.Post("uninstallExtension", php80Controller.UninstallExtension)
})
facades.Route().Prefix("api/plugins/php81").Middleware(middleware.Jwt()).Group(func(route route.Route) {
php81Controller := php81.NewPhp81Controller()
route.Get("status", php81Controller.Status)
route.Post("reload", php81Controller.Reload)
route.Post("start", php81Controller.Start)
route.Post("stop", php81Controller.Stop)
route.Post("restart", php81Controller.Restart)
route.Get("load", php81Controller.Load)
route.Get("config", php81Controller.GetConfig)
route.Post("config", php81Controller.SaveConfig)
route.Get("errorLog", php81Controller.ErrorLog)
route.Get("slowLog", php81Controller.SlowLog)
route.Post("clearErrorLog", php81Controller.ClearErrorLog)
route.Post("clearSlowLog", php81Controller.ClearSlowLog)
route.Get("extensions", php81Controller.GetExtensionList)
route.Post("installExtension", php81Controller.InstallExtension)
route.Post("uninstallExtension", php81Controller.UninstallExtension)
})
facades.Route().Prefix("api/plugins/php82").Middleware(middleware.Jwt()).Group(func(route route.Route) {
php82Controller := php82.NewPhp82Controller()
route.Get("status", php82Controller.Status)
route.Post("reload", php82Controller.Reload)
route.Post("start", php82Controller.Start)
route.Post("stop", php82Controller.Stop)
route.Post("restart", php82Controller.Restart)
route.Get("load", php82Controller.Load)
route.Get("config", php82Controller.GetConfig)
route.Post("config", php82Controller.SaveConfig)
route.Get("errorLog", php82Controller.ErrorLog)
route.Get("slowLog", php82Controller.SlowLog)
route.Post("clearErrorLog", php82Controller.ClearErrorLog)
route.Post("clearSlowLog", php82Controller.ClearSlowLog)
route.Get("extensions", php82Controller.GetExtensionList)
route.Post("installExtension", php82Controller.InstallExtension)
route.Post("uninstallExtension", php82Controller.UninstallExtension)
})
facades.Route().Prefix("api/plugins/phpmyadmin").Middleware(middleware.Jwt()).Group(func(route route.Route) {
phpMyAdminController := phpmyadmin.NewPhpMyAdminController()
route.Get("info", phpMyAdminController.Info)