diff --git a/app/http/controllers/plugins/php74_controller.go b/app/http/controllers/plugins/php74_controller.go
deleted file mode 100644
index 4dce0906..00000000
--- a/app/http/controllers/plugins/php74_controller.go
+++ /dev/null
@@ -1,273 +0,0 @@
-package plugins
-
-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/internal"
- "panel/internal/services"
- "panel/pkg/tools"
-)
-
-type Php74Controller struct {
- setting internal.Setting
- task internal.Task
- version string
-}
-
-func NewPhp74Controller() *Php74Controller {
- return &Php74Controller{
- setting: services.NewSettingImpl(),
- task: services.NewTaskImpl(),
- version: "74",
- }
-}
-
-func (r *Php74Controller) Status(ctx http.Context) http.Response {
- status, err := tools.ServiceStatus("php-fpm-" + r.version)
- if err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
- }
-
- return controllers.Success(ctx, status)
-}
-
-func (r *Php74Controller) Reload(ctx http.Context) http.Response {
- if err := tools.ServiceReload("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "重载PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php74Controller) Start(ctx http.Context) http.Response {
- if err := tools.ServiceStart("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "启动PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php74Controller) Stop(ctx http.Context) http.Response {
- if err := tools.ServiceStop("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "停止PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php74Controller) Restart(ctx http.Context) http.Response {
- if err := tools.ServiceRestart("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "重启PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php74Controller) GetConfig(ctx http.Context) http.Response {
- config, err := tools.Read("/www/server/php/" + r.version + "/etc/php.ini")
- if err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"配置失败")
- }
-
- return controllers.Success(ctx, config)
-}
-
-func (r *Php74Controller) SaveConfig(ctx http.Context) http.Response {
- config := ctx.Request().Input("config")
- if err := tools.Write("/www/server/php/"+r.version+"/etc/php.ini", config, 0644); err != nil {
- return nil
- }
- return r.Reload(ctx)
-}
-
-func (r *Php74Controller) Load(ctx http.Context) http.Response {
- client := req.C().SetTimeout(10 * time.Second)
- resp, err := client.R().Get("http://127.0.0.1/phpfpm_status/" + r.version)
- if err != nil || !resp.IsSuccessState() {
- facades.Log().Info("获取PHP-" + r.version + "运行状态失败")
- return controllers.Error(ctx, http.StatusInternalServerError, "[PHP-"+r.version+"] 获取运行状态失败")
- }
-
- 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])
- }
- }
-
- return controllers.Success(ctx, data)
-}
-
-func (r *Php74Controller) ErrorLog(ctx http.Context) http.Response {
- log, _ := tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/php-fpm.log")
- return controllers.Success(ctx, log)
-}
-
-func (r *Php74Controller) SlowLog(ctx http.Context) http.Response {
- log, _ := tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/slow.log")
- return controllers.Success(ctx, log)
-}
-
-func (r *Php74Controller) ClearErrorLog(ctx http.Context) http.Response {
- if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/php-fpm.log"); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, out)
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php74Controller) ClearSlowLog(ctx http.Context) http.Response {
- if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/slow.log"); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, out)
- }
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php74Controller) GetExtensionList(ctx http.Context) http.Response {
- extensions := r.GetExtensions()
- return controllers.Success(ctx, extensions)
-}
-
-func (r *Php74Controller) InstallExtension(ctx http.Context) http.Response {
- slug := ctx.Request().Input("slug")
- if len(slug) == 0 {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "参数错误")
- }
-
- extensions := r.GetExtensions()
- for _, item := range extensions {
- if item.Slug == slug {
- if item.Installed {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展已安装")
- }
-
- var task models.Task
- task.Name = "安装PHP-" + r.version + "扩展-" + item.Name
- task.Status = models.TaskStatusWaiting
- task.Shell = `bash '/www/panel/scripts/php_extensions/` + item.Slug + `.sh' install ` + r.version + ` >> '/tmp/` + item.Slug + `.log' 2>&1`
- task.Log = "/tmp/" + item.Slug + ".log"
- if err := facades.Orm().Query().Create(&task); err != nil {
- facades.Log().Info("[PHP-" + r.version + "] 创建安装拓展任务失败:" + err.Error())
- return controllers.ErrorSystem(ctx)
- }
-
- r.task.Process(task.ID)
-
- return controllers.Success(ctx, true)
- }
- }
-
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展不存在")
-}
-
-func (r *Php74Controller) UninstallExtension(ctx http.Context) http.Response {
- slug := ctx.Request().Input("slug")
- if len(slug) == 0 {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "参数错误")
- }
-
- extensions := r.GetExtensions()
- for _, item := range extensions {
- if item.Slug == slug {
- if !item.Installed {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展未安装")
- }
-
- var task models.Task
- task.Name = "卸载PHP-" + r.version + "扩展-" + item.Name
- task.Status = models.TaskStatusWaiting
- task.Shell = `bash '/www/panel/scripts/php_extensions/` + item.Slug + `.sh' uninstall ` + r.version + ` >> '/tmp/` + item.Slug + `.log' 2>&1`
- task.Log = "/tmp/" + item.Slug + ".log"
- if err := facades.Orm().Query().Create(&task); err != nil {
- facades.Log().Info("[PHP-" + r.version + "] 创建卸载拓展任务失败:" + err.Error())
- return controllers.ErrorSystem(ctx)
- }
-
- r.task.Process(task.ID)
-
- return controllers.Success(ctx, true)
- }
- }
-
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展不存在")
-}
-
-func (r *Php74Controller) GetExtensions() []PHPExtension {
- var extensions []PHPExtension
- extensions = append(extensions, PHPExtension{
- Name: "OPcache",
- Slug: "Zend OPcache",
- Description: "OPcache 通过将 PHP 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能,存储预编译字节码可以省去每次加载和解析 PHP 脚本的开销。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "PhpRedis",
- Slug: "redis",
- Description: "PhpRedis 是一个用 C 语言编写的 PHP 模块,用来连接并操作 Redis 数据库上的数据。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "ImageMagick",
- Slug: "imagick",
- Description: "ImageMagick 是一个免费的创建、编辑、合成图片的软件。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "Exif",
- Slug: "exif",
- Description: "通过 exif 扩展,你可以操作图像元数据。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "pdo_pgsql",
- Slug: "pdo_pgsql",
- Description: "(需先安装PostgreSQL)pdo_pgsql 是一个驱动程序,它实现了 PHP 数据对象(PDO)接口以启用从 PHP 到 PostgreSQL 数据库的访问。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "ionCube",
- Slug: "ionCube Loader",
- Description: "ionCube 是一个专业级的 PHP 加密解密工具。",
- Installed: false,
- })
-
- raw, err := tools.Exec("/www/server/php/" + r.version + "/bin/php -m")
- if err != nil {
- return extensions
- }
-
- 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
-}
diff --git a/app/http/controllers/plugins/php80_controller.go b/app/http/controllers/plugins/php80_controller.go
deleted file mode 100644
index a4a19c53..00000000
--- a/app/http/controllers/plugins/php80_controller.go
+++ /dev/null
@@ -1,273 +0,0 @@
-package plugins
-
-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/internal"
- "panel/internal/services"
- "panel/pkg/tools"
-)
-
-type Php80Controller struct {
- setting internal.Setting
- task internal.Task
- version string
-}
-
-func NewPhp80Controller() *Php80Controller {
- return &Php80Controller{
- setting: services.NewSettingImpl(),
- task: services.NewTaskImpl(),
- version: "80",
- }
-}
-
-func (r *Php80Controller) Status(ctx http.Context) http.Response {
- status, err := tools.ServiceStatus("php-fpm-" + r.version)
- if err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
- }
-
- return controllers.Success(ctx, status)
-}
-
-func (r *Php80Controller) Reload(ctx http.Context) http.Response {
- if err := tools.ServiceReload("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "重载PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php80Controller) Start(ctx http.Context) http.Response {
- if err := tools.ServiceStart("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "启动PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php80Controller) Stop(ctx http.Context) http.Response {
- if err := tools.ServiceStop("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "停止PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php80Controller) Restart(ctx http.Context) http.Response {
- if err := tools.ServiceRestart("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "重启PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php80Controller) GetConfig(ctx http.Context) http.Response {
- config, err := tools.Read("/www/server/php/" + r.version + "/etc/php.ini")
- if err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"配置失败")
- }
-
- return controllers.Success(ctx, config)
-}
-
-func (r *Php80Controller) SaveConfig(ctx http.Context) http.Response {
- config := ctx.Request().Input("config")
- if err := tools.Write("/www/server/php/"+r.version+"/etc/php.ini", config, 0644); err != nil {
- return nil
- }
- return r.Reload(ctx)
-}
-
-func (r *Php80Controller) Load(ctx http.Context) http.Response {
- client := req.C().SetTimeout(10 * time.Second)
- resp, err := client.R().Get("http://127.0.0.1/phpfpm_status/" + r.version)
- if err != nil || !resp.IsSuccessState() {
- facades.Log().Info("获取PHP-" + r.version + "运行状态失败")
- return controllers.Error(ctx, http.StatusInternalServerError, "[PHP-"+r.version+"] 获取运行状态失败")
- }
-
- 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])
- }
- }
-
- return controllers.Success(ctx, data)
-}
-
-func (r *Php80Controller) ErrorLog(ctx http.Context) http.Response {
- log, _ := tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/php-fpm.log")
- return controllers.Success(ctx, log)
-}
-
-func (r *Php80Controller) SlowLog(ctx http.Context) http.Response {
- log, _ := tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/slow.log")
- return controllers.Success(ctx, log)
-}
-
-func (r *Php80Controller) ClearErrorLog(ctx http.Context) http.Response {
- if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/php-fpm.log"); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, out)
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php80Controller) ClearSlowLog(ctx http.Context) http.Response {
- if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/slow.log"); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, out)
- }
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php80Controller) GetExtensionList(ctx http.Context) http.Response {
- extensions := r.GetExtensions()
- return controllers.Success(ctx, extensions)
-}
-
-func (r *Php80Controller) InstallExtension(ctx http.Context) http.Response {
- slug := ctx.Request().Input("slug")
- if len(slug) == 0 {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "参数错误")
- }
-
- extensions := r.GetExtensions()
- for _, item := range extensions {
- if item.Slug == slug {
- if item.Installed {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展已安装")
- }
-
- var task models.Task
- task.Name = "安装PHP-" + r.version + "扩展-" + item.Name
- task.Status = models.TaskStatusWaiting
- task.Shell = `bash '/www/panel/scripts/php_extensions/` + item.Slug + `.sh' install ` + r.version + ` >> '/tmp/` + item.Slug + `.log' 2>&1`
- task.Log = "/tmp/" + item.Slug + ".log"
- if err := facades.Orm().Query().Create(&task); err != nil {
- facades.Log().Info("[PHP-" + r.version + "] 创建安装拓展任务失败:" + err.Error())
- return controllers.ErrorSystem(ctx)
- }
-
- r.task.Process(task.ID)
-
- return controllers.Success(ctx, true)
- }
- }
-
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展不存在")
-}
-
-func (r *Php80Controller) UninstallExtension(ctx http.Context) http.Response {
- slug := ctx.Request().Input("slug")
- if len(slug) == 0 {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "参数错误")
- }
-
- extensions := r.GetExtensions()
- for _, item := range extensions {
- if item.Slug == slug {
- if !item.Installed {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展未安装")
- }
-
- var task models.Task
- task.Name = "卸载PHP-" + r.version + "扩展-" + item.Name
- task.Status = models.TaskStatusWaiting
- task.Shell = `bash '/www/panel/scripts/php_extensions/` + item.Slug + `.sh' uninstall ` + r.version + ` >> '/tmp/` + item.Slug + `.log' 2>&1`
- task.Log = "/tmp/" + item.Slug + ".log"
- if err := facades.Orm().Query().Create(&task); err != nil {
- facades.Log().Info("[PHP-" + r.version + "] 创建卸载拓展任务失败:" + err.Error())
- return controllers.ErrorSystem(ctx)
- }
-
- r.task.Process(task.ID)
-
- return controllers.Success(ctx, true)
- }
- }
-
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展不存在")
-}
-
-func (r *Php80Controller) GetExtensions() []PHPExtension {
- var extensions []PHPExtension
- extensions = append(extensions, PHPExtension{
- Name: "OPcache",
- Slug: "Zend OPcache",
- Description: "OPcache 通过将 PHP 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能,存储预编译字节码可以省去每次加载和解析 PHP 脚本的开销。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "PhpRedis",
- Slug: "redis",
- Description: "PhpRedis 是一个用 C 语言编写的 PHP 模块,用来连接并操作 Redis 数据库上的数据。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "ImageMagick",
- Slug: "imagick",
- Description: "ImageMagick 是一个免费的创建、编辑、合成图片的软件。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "Exif",
- Slug: "exif",
- Description: "通过 exif 扩展,你可以操作图像元数据。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "pdo_pgsql",
- Slug: "pdo_pgsql",
- Description: "(需先安装PostgreSQL)pdo_pgsql 是一个驱动程序,它实现了 PHP 数据对象(PDO)接口以启用从 PHP 到 PostgreSQL 数据库的访问。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "ionCube",
- Slug: "ionCube Loader",
- Description: "ionCube 是一个专业级的 PHP 加密解密工具。",
- Installed: false,
- })
-
- raw, err := tools.Exec("/www/server/php/" + r.version + "/bin/php -m")
- if err != nil {
- return extensions
- }
-
- 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
-}
diff --git a/app/http/controllers/plugins/php81_controller.go b/app/http/controllers/plugins/php81_controller.go
deleted file mode 100644
index a234dd07..00000000
--- a/app/http/controllers/plugins/php81_controller.go
+++ /dev/null
@@ -1,273 +0,0 @@
-package plugins
-
-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/internal"
- "panel/internal/services"
- "panel/pkg/tools"
-)
-
-type Php81Controller struct {
- setting internal.Setting
- task internal.Task
- version string
-}
-
-func NewPhp81Controller() *Php81Controller {
- return &Php81Controller{
- setting: services.NewSettingImpl(),
- task: services.NewTaskImpl(),
- version: "81",
- }
-}
-
-func (r *Php81Controller) Status(ctx http.Context) http.Response {
- status, err := tools.ServiceStatus("php-fpm-" + r.version)
- if err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
- }
-
- return controllers.Success(ctx, status)
-}
-
-func (r *Php81Controller) Reload(ctx http.Context) http.Response {
- if err := tools.ServiceReload("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "重载PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php81Controller) Start(ctx http.Context) http.Response {
- if err := tools.ServiceStart("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "启动PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php81Controller) Stop(ctx http.Context) http.Response {
- if err := tools.ServiceStop("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "停止PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php81Controller) Restart(ctx http.Context) http.Response {
- if err := tools.ServiceRestart("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "重启PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php81Controller) GetConfig(ctx http.Context) http.Response {
- config, err := tools.Read("/www/server/php/" + r.version + "/etc/php.ini")
- if err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"配置失败")
- }
-
- return controllers.Success(ctx, config)
-}
-
-func (r *Php81Controller) SaveConfig(ctx http.Context) http.Response {
- config := ctx.Request().Input("config")
- if err := tools.Write("/www/server/php/"+r.version+"/etc/php.ini", config, 0644); err != nil {
- return nil
- }
- return r.Reload(ctx)
-}
-
-func (r *Php81Controller) Load(ctx http.Context) http.Response {
- client := req.C().SetTimeout(10 * time.Second)
- resp, err := client.R().Get("http://127.0.0.1/phpfpm_status/" + r.version)
- if err != nil || !resp.IsSuccessState() {
- facades.Log().Info("获取PHP-" + r.version + "运行状态失败")
- return controllers.Error(ctx, http.StatusInternalServerError, "[PHP-"+r.version+"] 获取运行状态失败")
- }
-
- 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])
- }
- }
-
- return controllers.Success(ctx, data)
-}
-
-func (r *Php81Controller) ErrorLog(ctx http.Context) http.Response {
- log, _ := tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/php-fpm.log")
- return controllers.Success(ctx, log)
-}
-
-func (r *Php81Controller) SlowLog(ctx http.Context) http.Response {
- log, _ := tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/slow.log")
- return controllers.Success(ctx, log)
-}
-
-func (r *Php81Controller) ClearErrorLog(ctx http.Context) http.Response {
- if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/php-fpm.log"); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, out)
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php81Controller) ClearSlowLog(ctx http.Context) http.Response {
- if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/slow.log"); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, out)
- }
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php81Controller) GetExtensionList(ctx http.Context) http.Response {
- extensions := r.GetExtensions()
- return controllers.Success(ctx, extensions)
-}
-
-func (r *Php81Controller) InstallExtension(ctx http.Context) http.Response {
- slug := ctx.Request().Input("slug")
- if len(slug) == 0 {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "参数错误")
- }
-
- extensions := r.GetExtensions()
- for _, item := range extensions {
- if item.Slug == slug {
- if item.Installed {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展已安装")
- }
-
- var task models.Task
- task.Name = "安装PHP-" + r.version + "扩展-" + item.Name
- task.Status = models.TaskStatusWaiting
- task.Shell = `bash '/www/panel/scripts/php_extensions/` + item.Slug + `.sh' install ` + r.version + ` >> '/tmp/` + item.Slug + `.log' 2>&1`
- task.Log = "/tmp/" + item.Slug + ".log"
- if err := facades.Orm().Query().Create(&task); err != nil {
- facades.Log().Info("[PHP-" + r.version + "] 创建安装拓展任务失败:" + err.Error())
- return controllers.ErrorSystem(ctx)
- }
-
- r.task.Process(task.ID)
-
- return controllers.Success(ctx, true)
- }
- }
-
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展不存在")
-}
-
-func (r *Php81Controller) UninstallExtension(ctx http.Context) http.Response {
- slug := ctx.Request().Input("slug")
- if len(slug) == 0 {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "参数错误")
- }
-
- extensions := r.GetExtensions()
- for _, item := range extensions {
- if item.Slug == slug {
- if !item.Installed {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展未安装")
- }
-
- var task models.Task
- task.Name = "卸载PHP-" + r.version + "扩展-" + item.Name
- task.Status = models.TaskStatusWaiting
- task.Shell = `bash '/www/panel/scripts/php_extensions/` + item.Slug + `.sh' uninstall ` + r.version + ` >> '/tmp/` + item.Slug + `.log' 2>&1`
- task.Log = "/tmp/" + item.Slug + ".log"
- if err := facades.Orm().Query().Create(&task); err != nil {
- facades.Log().Info("[PHP-" + r.version + "] 创建卸载拓展任务失败:" + err.Error())
- return controllers.ErrorSystem(ctx)
- }
-
- r.task.Process(task.ID)
-
- return controllers.Success(ctx, true)
- }
- }
-
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展不存在")
-}
-
-func (r *Php81Controller) GetExtensions() []PHPExtension {
- var extensions []PHPExtension
- extensions = append(extensions, PHPExtension{
- Name: "OPcache",
- Slug: "Zend OPcache",
- Description: "OPcache 通过将 PHP 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能,存储预编译字节码可以省去每次加载和解析 PHP 脚本的开销。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "PhpRedis",
- Slug: "redis",
- Description: "PhpRedis 是一个用 C 语言编写的 PHP 模块,用来连接并操作 Redis 数据库上的数据。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "ImageMagick",
- Slug: "imagick",
- Description: "ImageMagick 是一个免费的创建、编辑、合成图片的软件。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "Exif",
- Slug: "exif",
- Description: "通过 exif 扩展,你可以操作图像元数据。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "pdo_pgsql",
- Slug: "pdo_pgsql",
- Description: "(需先安装PostgreSQL)pdo_pgsql 是一个驱动程序,它实现了 PHP 数据对象(PDO)接口以启用从 PHP 到 PostgreSQL 数据库的访问。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "ionCube",
- Slug: "ionCube Loader",
- Description: "ionCube 是一个专业级的 PHP 加密解密工具。",
- Installed: false,
- })
-
- raw, err := tools.Exec("/www/server/php/" + r.version + "/bin/php -m")
- if err != nil {
- return extensions
- }
-
- 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
-}
diff --git a/app/http/controllers/plugins/php82_controller.go b/app/http/controllers/plugins/php82_controller.go
deleted file mode 100644
index a89f2982..00000000
--- a/app/http/controllers/plugins/php82_controller.go
+++ /dev/null
@@ -1,273 +0,0 @@
-package plugins
-
-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/internal"
- "panel/internal/services"
- "panel/pkg/tools"
-)
-
-type Php82Controller struct {
- setting internal.Setting
- task internal.Task
- version string
-}
-
-func NewPhp82Controller() *Php82Controller {
- return &Php82Controller{
- setting: services.NewSettingImpl(),
- task: services.NewTaskImpl(),
- version: "82",
- }
-}
-
-func (r *Php82Controller) Status(ctx http.Context) http.Response {
- status, err := tools.ServiceStatus("php-fpm-" + r.version)
- if err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
- }
-
- return controllers.Success(ctx, status)
-}
-
-func (r *Php82Controller) Reload(ctx http.Context) http.Response {
- if err := tools.ServiceReload("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "重载PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php82Controller) Start(ctx http.Context) http.Response {
- if err := tools.ServiceStart("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "启动PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php82Controller) Stop(ctx http.Context) http.Response {
- if err := tools.ServiceStop("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "停止PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php82Controller) Restart(ctx http.Context) http.Response {
- if err := tools.ServiceRestart("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "重启PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php82Controller) GetConfig(ctx http.Context) http.Response {
- config, err := tools.Read("/www/server/php/" + r.version + "/etc/php.ini")
- if err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"配置失败")
- }
-
- return controllers.Success(ctx, config)
-}
-
-func (r *Php82Controller) SaveConfig(ctx http.Context) http.Response {
- config := ctx.Request().Input("config")
- if err := tools.Write("/www/server/php/"+r.version+"/etc/php.ini", config, 0644); err != nil {
- return nil
- }
- return r.Reload(ctx)
-}
-
-func (r *Php82Controller) Load(ctx http.Context) http.Response {
- client := req.C().SetTimeout(10 * time.Second)
- resp, err := client.R().Get("http://127.0.0.1/phpfpm_status/" + r.version)
- if err != nil || !resp.IsSuccessState() {
- facades.Log().Info("获取PHP-" + r.version + "运行状态失败")
- return controllers.Error(ctx, http.StatusInternalServerError, "[PHP-"+r.version+"] 获取运行状态失败")
- }
-
- 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])
- }
- }
-
- return controllers.Success(ctx, data)
-}
-
-func (r *Php82Controller) ErrorLog(ctx http.Context) http.Response {
- log, _ := tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/php-fpm.log")
- return controllers.Success(ctx, log)
-}
-
-func (r *Php82Controller) SlowLog(ctx http.Context) http.Response {
- log, _ := tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/slow.log")
- return controllers.Success(ctx, log)
-}
-
-func (r *Php82Controller) ClearErrorLog(ctx http.Context) http.Response {
- if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/php-fpm.log"); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, out)
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php82Controller) ClearSlowLog(ctx http.Context) http.Response {
- if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/slow.log"); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, out)
- }
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php82Controller) GetExtensionList(ctx http.Context) http.Response {
- extensions := r.GetExtensions()
- return controllers.Success(ctx, extensions)
-}
-
-func (r *Php82Controller) InstallExtension(ctx http.Context) http.Response {
- slug := ctx.Request().Input("slug")
- if len(slug) == 0 {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "参数错误")
- }
-
- extensions := r.GetExtensions()
- for _, item := range extensions {
- if item.Slug == slug {
- if item.Installed {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展已安装")
- }
-
- var task models.Task
- task.Name = "安装PHP-" + r.version + "扩展-" + item.Name
- task.Status = models.TaskStatusWaiting
- task.Shell = `bash '/www/panel/scripts/php_extensions/` + item.Slug + `.sh' install ` + r.version + ` >> '/tmp/` + item.Slug + `.log' 2>&1`
- task.Log = "/tmp/" + item.Slug + ".log"
- if err := facades.Orm().Query().Create(&task); err != nil {
- facades.Log().Info("[PHP-" + r.version + "] 创建安装拓展任务失败:" + err.Error())
- return controllers.ErrorSystem(ctx)
- }
-
- r.task.Process(task.ID)
-
- return controllers.Success(ctx, true)
- }
- }
-
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展不存在")
-}
-
-func (r *Php82Controller) UninstallExtension(ctx http.Context) http.Response {
- slug := ctx.Request().Input("slug")
- if len(slug) == 0 {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "参数错误")
- }
-
- extensions := r.GetExtensions()
- for _, item := range extensions {
- if item.Slug == slug {
- if !item.Installed {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展未安装")
- }
-
- var task models.Task
- task.Name = "卸载PHP-" + r.version + "扩展-" + item.Name
- task.Status = models.TaskStatusWaiting
- task.Shell = `bash '/www/panel/scripts/php_extensions/` + item.Slug + `.sh' uninstall ` + r.version + ` >> '/tmp/` + item.Slug + `.log' 2>&1`
- task.Log = "/tmp/" + item.Slug + ".log"
- if err := facades.Orm().Query().Create(&task); err != nil {
- facades.Log().Info("[PHP-" + r.version + "] 创建卸载拓展任务失败:" + err.Error())
- return controllers.ErrorSystem(ctx)
- }
-
- r.task.Process(task.ID)
-
- return controllers.Success(ctx, true)
- }
- }
-
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展不存在")
-}
-
-func (r *Php82Controller) GetExtensions() []PHPExtension {
- var extensions []PHPExtension
- extensions = append(extensions, PHPExtension{
- Name: "OPcache",
- Slug: "Zend OPcache",
- Description: "OPcache 通过将 PHP 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能,存储预编译字节码可以省去每次加载和解析 PHP 脚本的开销。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "PhpRedis",
- Slug: "redis",
- Description: "PhpRedis 是一个用 C 语言编写的 PHP 模块,用来连接并操作 Redis 数据库上的数据。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "ImageMagick",
- Slug: "imagick",
- Description: "ImageMagick 是一个免费的创建、编辑、合成图片的软件。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "Exif",
- Slug: "exif",
- Description: "通过 exif 扩展,你可以操作图像元数据。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "pdo_pgsql",
- Slug: "pdo_pgsql",
- Description: "(需先安装PostgreSQL)pdo_pgsql 是一个驱动程序,它实现了 PHP 数据对象(PDO)接口以启用从 PHP 到 PostgreSQL 数据库的访问。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "ionCube",
- Slug: "ionCube Loader",
- Description: "ionCube 是一个专业级的 PHP 加密解密工具。",
- Installed: false,
- })
-
- raw, err := tools.Exec("/www/server/php/" + r.version + "/bin/php -m")
- if err != nil {
- return extensions
- }
-
- 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
-}
diff --git a/app/http/controllers/plugins/php83_controller.go b/app/http/controllers/plugins/php83_controller.go
deleted file mode 100644
index 0e3b9da9..00000000
--- a/app/http/controllers/plugins/php83_controller.go
+++ /dev/null
@@ -1,267 +0,0 @@
-package plugins
-
-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/internal"
- "panel/internal/services"
- "panel/pkg/tools"
-)
-
-type Php83Controller struct {
- setting internal.Setting
- task internal.Task
- version string
-}
-
-func NewPhp83Controller() *Php83Controller {
- return &Php83Controller{
- setting: services.NewSettingImpl(),
- task: services.NewTaskImpl(),
- version: "83",
- }
-}
-
-func (r *Php83Controller) Status(ctx http.Context) http.Response {
- status, err := tools.ServiceStatus("php-fpm-" + r.version)
- if err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
- }
-
- return controllers.Success(ctx, status)
-}
-
-func (r *Php83Controller) Reload(ctx http.Context) http.Response {
- if err := tools.ServiceReload("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "重载PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php83Controller) Start(ctx http.Context) http.Response {
- if err := tools.ServiceStart("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "启动PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php83Controller) Stop(ctx http.Context) http.Response {
- if err := tools.ServiceStop("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "停止PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php83Controller) Restart(ctx http.Context) http.Response {
- if err := tools.ServiceRestart("php-fpm-" + r.version); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "重启PHP-"+r.version+"失败")
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php83Controller) GetConfig(ctx http.Context) http.Response {
- config, err := tools.Read("/www/server/php/" + r.version + "/etc/php.ini")
- if err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"配置失败")
- }
-
- return controllers.Success(ctx, config)
-}
-
-func (r *Php83Controller) SaveConfig(ctx http.Context) http.Response {
- config := ctx.Request().Input("config")
- if err := tools.Write("/www/server/php/"+r.version+"/etc/php.ini", config, 0644); err != nil {
- return nil
- }
- return r.Reload(ctx)
-}
-
-func (r *Php83Controller) Load(ctx http.Context) http.Response {
- client := req.C().SetTimeout(10 * time.Second)
- resp, err := client.R().Get("http://127.0.0.1/phpfpm_status/" + r.version)
- if err != nil || !resp.IsSuccessState() {
- facades.Log().Info("获取PHP-" + r.version + "运行状态失败")
- return controllers.Error(ctx, http.StatusInternalServerError, "[PHP-"+r.version+"] 获取运行状态失败")
- }
-
- 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])
- }
- }
-
- return controllers.Success(ctx, data)
-}
-
-func (r *Php83Controller) ErrorLog(ctx http.Context) http.Response {
- log, _ := tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/php-fpm.log")
- return controllers.Success(ctx, log)
-}
-
-func (r *Php83Controller) SlowLog(ctx http.Context) http.Response {
- log, _ := tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/slow.log")
- return controllers.Success(ctx, log)
-}
-
-func (r *Php83Controller) ClearErrorLog(ctx http.Context) http.Response {
- if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/php-fpm.log"); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, out)
- }
-
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php83Controller) ClearSlowLog(ctx http.Context) http.Response {
- if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/slow.log"); err != nil {
- return controllers.Error(ctx, http.StatusInternalServerError, out)
- }
- return controllers.Success(ctx, nil)
-}
-
-func (r *Php83Controller) GetExtensionList(ctx http.Context) http.Response {
- extensions := r.GetExtensions()
- return controllers.Success(ctx, extensions)
-}
-
-func (r *Php83Controller) InstallExtension(ctx http.Context) http.Response {
- slug := ctx.Request().Input("slug")
- if len(slug) == 0 {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "参数错误")
- }
-
- extensions := r.GetExtensions()
- for _, item := range extensions {
- if item.Slug == slug {
- if item.Installed {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展已安装")
- }
-
- var task models.Task
- task.Name = "安装PHP-" + r.version + "扩展-" + item.Name
- task.Status = models.TaskStatusWaiting
- task.Shell = `bash '/www/panel/scripts/php_extensions/` + item.Slug + `.sh' install ` + r.version + ` >> '/tmp/` + item.Slug + `.log' 2>&1`
- task.Log = "/tmp/" + item.Slug + ".log"
- if err := facades.Orm().Query().Create(&task); err != nil {
- facades.Log().Info("[PHP-" + r.version + "] 创建安装拓展任务失败:" + err.Error())
- return controllers.ErrorSystem(ctx)
- }
-
- r.task.Process(task.ID)
-
- return controllers.Success(ctx, true)
- }
- }
-
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展不存在")
-}
-
-func (r *Php83Controller) UninstallExtension(ctx http.Context) http.Response {
- slug := ctx.Request().Input("slug")
- if len(slug) == 0 {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "参数错误")
- }
-
- extensions := r.GetExtensions()
- for _, item := range extensions {
- if item.Slug == slug {
- if !item.Installed {
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展未安装")
- }
-
- var task models.Task
- task.Name = "卸载PHP-" + r.version + "扩展-" + item.Name
- task.Status = models.TaskStatusWaiting
- task.Shell = `bash '/www/panel/scripts/php_extensions/` + item.Slug + `.sh' uninstall ` + r.version + ` >> '/tmp/` + item.Slug + `.log' 2>&1`
- task.Log = "/tmp/" + item.Slug + ".log"
- if err := facades.Orm().Query().Create(&task); err != nil {
- facades.Log().Info("[PHP-" + r.version + "] 创建卸载拓展任务失败:" + err.Error())
- return controllers.ErrorSystem(ctx)
- }
-
- r.task.Process(task.ID)
-
- return controllers.Success(ctx, true)
- }
- }
-
- return controllers.Error(ctx, http.StatusUnprocessableEntity, "扩展不存在")
-}
-
-func (r *Php83Controller) GetExtensions() []PHPExtension {
- var extensions []PHPExtension
- extensions = append(extensions, PHPExtension{
- Name: "OPcache",
- Slug: "Zend OPcache",
- Description: "OPcache 通过将 PHP 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能,存储预编译字节码可以省去每次加载和解析 PHP 脚本的开销。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "PhpRedis",
- Slug: "redis",
- Description: "PhpRedis 是一个用 C 语言编写的 PHP 模块,用来连接并操作 Redis 数据库上的数据。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "ImageMagick",
- Slug: "imagick",
- Description: "ImageMagick 是一个免费的创建、编辑、合成图片的软件。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "Exif",
- Slug: "exif",
- Description: "通过 exif 扩展,你可以操作图像元数据。",
- Installed: false,
- })
- extensions = append(extensions, PHPExtension{
- Name: "pdo_pgsql",
- Slug: "pdo_pgsql",
- Description: "(需先安装PostgreSQL)pdo_pgsql 是一个驱动程序,它实现了 PHP 数据对象(PDO)接口以启用从 PHP 到 PostgreSQL 数据库的访问。",
- Installed: false,
- })
-
- raw, err := tools.Exec("/www/server/php/" + r.version + "/bin/php -m")
- if err != nil {
- return extensions
- }
-
- 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
-}
diff --git a/app/http/controllers/plugins/php_controller.go b/app/http/controllers/plugins/php_controller.go
new file mode 100644
index 00000000..ab249ca2
--- /dev/null
+++ b/app/http/controllers/plugins/php_controller.go
@@ -0,0 +1,149 @@
+package plugins
+
+import (
+ "github.com/goravel/framework/contracts/http"
+ "panel/app/http/controllers"
+ "panel/internal"
+ "panel/internal/services"
+)
+
+type PHPController struct {
+ service internal.PHP
+}
+
+func NewPHPController(version uint) *PHPController {
+ return &PHPController{
+ service: services.NewPHPImpl(version),
+ }
+}
+
+func (r *PHPController) Status(ctx http.Context) http.Response {
+ status, err := r.service.Status()
+ if err != nil {
+ return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
+ }
+
+ return controllers.Success(ctx, status)
+}
+
+func (r *PHPController) Reload(ctx http.Context) http.Response {
+ if err := r.service.Reload(); err != nil {
+ return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
+ }
+
+ return controllers.Success(ctx, nil)
+}
+
+func (r *PHPController) Start(ctx http.Context) http.Response {
+ if err := r.service.Start(); err != nil {
+ return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
+ }
+
+ return controllers.Success(ctx, nil)
+}
+
+func (r *PHPController) Stop(ctx http.Context) http.Response {
+ if err := r.service.Stop(); err != nil {
+ return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
+ }
+
+ return controllers.Success(ctx, nil)
+}
+
+func (r *PHPController) Restart(ctx http.Context) http.Response {
+ if err := r.service.Restart(); err != nil {
+ return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
+ }
+
+ return controllers.Success(ctx, nil)
+}
+
+func (r *PHPController) GetConfig(ctx http.Context) http.Response {
+ config, err := r.service.GetConfig()
+ if err != nil {
+ return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
+ }
+
+ return controllers.Success(ctx, config)
+}
+
+func (r *PHPController) SaveConfig(ctx http.Context) http.Response {
+ config := ctx.Request().Input("config")
+ if err := r.service.SaveConfig(config); err != nil {
+ return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
+ }
+
+ return controllers.Success(ctx, nil)
+}
+
+func (r *PHPController) Load(ctx http.Context) http.Response {
+ load, err := r.service.Load()
+ if err != nil {
+ return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
+ }
+
+ return controllers.Success(ctx, load)
+}
+
+func (r *PHPController) ErrorLog(ctx http.Context) http.Response {
+ log, _ := r.service.GetErrorLog()
+ return controllers.Success(ctx, log)
+}
+
+func (r *PHPController) SlowLog(ctx http.Context) http.Response {
+ log, _ := r.service.GetSlowLog()
+ return controllers.Success(ctx, log)
+}
+
+func (r *PHPController) ClearErrorLog(ctx http.Context) http.Response {
+ err := r.service.ClearErrorLog()
+ if err != nil {
+ return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
+ }
+
+ return controllers.Success(ctx, nil)
+}
+
+func (r *PHPController) ClearSlowLog(ctx http.Context) http.Response {
+ err := r.service.ClearSlowLog()
+ if err != nil {
+ return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
+ }
+
+ return controllers.Success(ctx, nil)
+}
+
+func (r *PHPController) GetExtensionList(ctx http.Context) http.Response {
+ extensions, err := r.service.GetExtensions()
+ if err != nil {
+ return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
+ }
+
+ return controllers.Success(ctx, extensions)
+}
+
+func (r *PHPController) InstallExtension(ctx http.Context) http.Response {
+ slug := ctx.Request().Input("slug")
+ if len(slug) == 0 {
+ return controllers.Error(ctx, http.StatusUnprocessableEntity, "参数错误")
+ }
+
+ if err := r.service.InstallExtension(slug); err != nil {
+ return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
+ }
+
+ return controllers.Success(ctx, nil)
+}
+
+func (r *PHPController) UninstallExtension(ctx http.Context) http.Response {
+ slug := ctx.Request().Input("slug")
+ if len(slug) == 0 {
+ return controllers.Error(ctx, http.StatusUnprocessableEntity, "参数错误")
+ }
+
+ if err := r.service.UninstallExtension(slug); err != nil {
+ return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
+ }
+
+ return controllers.Success(ctx, nil)
+}
diff --git a/internal/constants.go b/internal/constants.go
new file mode 100644
index 00000000..afaee5ef
--- /dev/null
+++ b/internal/constants.go
@@ -0,0 +1,11 @@
+package internal
+
+type NV struct {
+ Name string `json:"name"`
+ Value string `json:"value"`
+}
+
+type KV struct {
+ Key string `json:"key"`
+ Value string `json:"value"`
+}
diff --git a/internal/php.go b/internal/php.go
new file mode 100644
index 00000000..be87f99b
--- /dev/null
+++ b/internal/php.go
@@ -0,0 +1,28 @@
+package internal
+
+type PHPExtension struct {
+ Name string `json:"name"`
+ Slug string `json:"slug"`
+ Description string `json:"description"`
+ Installed bool `json:"installed"`
+}
+
+type PHP interface {
+ Status() (bool, error)
+ Reload() error
+ Start() error
+ Stop() error
+ Restart() error
+ GetConfig() (string, error)
+ SaveConfig(config string) error
+ GetFPMConfig() (string, error)
+ SaveFPMConfig(config string) error
+ Load() ([]NV, error)
+ GetErrorLog() (string, error)
+ GetSlowLog() (string, error)
+ ClearErrorLog() error
+ ClearSlowLog() error
+ GetExtensions() ([]PHPExtension, error)
+ InstallExtension(slug string) error
+ UninstallExtension(slug string) error
+}
diff --git a/internal/plugin_list.go b/internal/plugin_list.go
new file mode 100644
index 00000000..b577424b
--- /dev/null
+++ b/internal/plugin_list.go
@@ -0,0 +1,218 @@
+// Package internal 插件定义文件
+package internal
+
+var PluginOpenResty = PanelPlugin{
+ Name: "OpenResty",
+ Description: "OpenResty® 是一款基于 NGINX 和 LuaJIT 的 Web 平台。",
+ Slug: "openresty",
+ Version: "1.25.3.1",
+ Requires: []string{},
+ Excludes: []string{},
+ Install: "bash /www/panel/scripts/openresty/install.sh",
+ Uninstall: "bash /www/panel/scripts/openresty/uninstall.sh",
+ Update: "bash /www/panel/scripts/openresty/install.sh",
+}
+
+var PluginMySQL57 = PanelPlugin{
+ Name: "MySQL-5.7",
+ Description: "MySQL 是最流行的关系型数据库管理系统之一,Oracle 旗下产品。(已停止维护,不建议使用!预计 2025 年 12 月移除)",
+ Slug: "mysql57",
+ Version: "5.7.44",
+ Requires: []string{},
+ Excludes: []string{"mysql80"},
+ Install: `bash /www/panel/scripts/mysql/install.sh 57`,
+ Uninstall: `bash /www/panel/scripts/mysql/uninstall.sh 57`,
+ Update: `bash /www/panel/scripts/mysql/update.sh 57`,
+}
+
+var PluginMySQL80 = PanelPlugin{
+ Name: "MySQL-8.0",
+ Description: "MySQL 是最流行的关系型数据库管理系统之一,Oracle 旗下产品。(建议内存 > 2G 安装)",
+ Slug: "mysql80",
+ Version: "8.0.36",
+ Requires: []string{},
+ Excludes: []string{"mysql57"},
+ Install: `bash /www/panel/scripts/mysql/install.sh 80`,
+ Uninstall: `bash /www/panel/scripts/mysql/uninstall.sh 80`,
+ Update: `bash /www/panel/scripts/mysql/update.sh 80`,
+}
+
+var PluginPostgreSQL15 = PanelPlugin{
+ Name: "PostgreSQL-15",
+ Description: "PostgreSQL 是世界上最先进的开源关系数据库,在类似 BSD 与 MIT 许可的 PostgreSQL 许可下发行。",
+ Slug: "postgresql15",
+ Version: "15.6",
+ Requires: []string{},
+ Excludes: []string{"postgresql16"},
+ Install: `bash /www/panel/scripts/postgresql/install.sh 15`,
+ Uninstall: `bash /www/panel/scripts/postgresql/uninstall.sh 15`,
+ Update: `bash /www/panel/scripts/postgresql/update.sh 15`,
+}
+
+var PluginPostgreSQL16 = PanelPlugin{
+ Name: "PostgreSQL-16",
+ Description: "PostgreSQL 是世界上最先进的开源关系数据库,在类似 BSD 与 MIT 许可的 PostgreSQL 许可下发行。",
+ Slug: "postgresql16",
+ Version: "16.2",
+ Requires: []string{},
+ Excludes: []string{"postgresql15"},
+ Install: `bash /www/panel/scripts/postgresql/install.sh 16`,
+ Uninstall: `bash /www/panel/scripts/postgresql/uninstall.sh 16`,
+ Update: `bash /www/panel/scripts/postgresql/update.sh 16`,
+}
+
+var PluginPHP74 = PanelPlugin{
+ Name: "PHP-7.4",
+ Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。(已停止维护,不建议使用!预计 2024 年 12 月移除)",
+ Slug: "php74",
+ Version: "7.4.33",
+ Requires: []string{},
+ Excludes: []string{},
+ Install: `bash /www/panel/scripts/php/install.sh 74`,
+ Uninstall: `bash /www/panel/scripts/php/uninstall.sh 74`,
+ Update: `bash /www/panel/scripts/php/install.sh 74`,
+}
+
+var PluginPHP80 = PanelPlugin{
+ Name: "PHP-8.0",
+ Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。(已停止维护,不建议使用!预计 2025 年 12 月移除)",
+ Slug: "php80",
+ Version: "8.0.30",
+ Requires: []string{},
+ Excludes: []string{},
+ Install: `bash /www/panel/scripts/php/install.sh 80`,
+ Uninstall: `bash /www/panel/scripts/php/uninstall.sh 80`,
+ Update: `bash /www/panel/scripts/php/install.sh 80`,
+}
+
+var PluginPHP81 = PanelPlugin{
+ Name: "PHP-8.1",
+ Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。",
+ Slug: "php81",
+ Version: "8.1.27",
+ 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`,
+}
+
+var PluginPHP82 = PanelPlugin{
+ Name: "PHP-8.2",
+ Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。",
+ Slug: "php82",
+ Version: "8.2.16",
+ 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`,
+}
+
+var PluginPHP83 = PanelPlugin{
+ Name: "PHP-8.3",
+ Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。",
+ Slug: "php83",
+ Version: "8.3.3",
+ Requires: []string{},
+ Excludes: []string{},
+ Install: `bash /www/panel/scripts/php/install.sh 83`,
+ Uninstall: `bash /www/panel/scripts/php/uninstall.sh 83`,
+ Update: `bash /www/panel/scripts/php/install.sh 83`,
+}
+
+var PluginPHPMyAdmin = PanelPlugin{
+ Name: "phpMyAdmin",
+ Description: "phpMyAdmin 是一个以 PHP 为基础,以 Web-Base 方式架构在网站主机上的 MySQL 数据库管理工具。",
+ Slug: "phpmyadmin",
+ Version: "5.2.1",
+ Requires: []string{},
+ Excludes: []string{},
+ Install: `bash /www/panel/scripts/phpmyadmin/install.sh`,
+ Uninstall: `bash /www/panel/scripts/phpmyadmin/uninstall.sh`,
+ Update: `bash /www/panel/scripts/phpmyadmin/uninstall.sh && bash /www/panel/scripts/phpmyadmin/install.sh`,
+}
+
+var PluginPureFTPd = PanelPlugin{
+ Name: "Pure-FTPd",
+ Description: "Pure-Ftpd 是一个快速、高效、轻便、安全的 FTP 服务器,它以安全和配置简单为设计目标,支持虚拟主机,IPV6,PAM 等功能。",
+ Slug: "pureftpd",
+ Version: "1.0.50",
+ Requires: []string{},
+ Excludes: []string{},
+ Install: `bash /www/panel/scripts/pureftpd/install.sh`,
+ Uninstall: `bash /www/panel/scripts/pureftpd/uninstall.sh`,
+ Update: `bash /www/panel/scripts/pureftpd/update.sh`,
+}
+
+var PluginRedis = PanelPlugin{
+ Name: "Redis",
+ Description: "Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。",
+ Slug: "redis",
+ Version: "7.2.4",
+ Requires: []string{},
+ Excludes: []string{},
+ Install: `bash /www/panel/scripts/redis/install.sh`,
+ Uninstall: `bash /www/panel/scripts/redis/uninstall.sh`,
+ Update: `bash /www/panel/scripts/redis/update.sh`,
+}
+
+var PluginS3fs = PanelPlugin{
+ Name: "S3fs",
+ Description: "S3fs 通过 FUSE 挂载兼容 S3 标准的存储桶,例如 Amazon S3、阿里云 OSS、腾讯云 COS、七牛云 Kodo 等。",
+ Slug: "s3fs",
+ Version: "1.9",
+ Requires: []string{},
+ Excludes: []string{},
+ Install: `bash /www/panel/scripts/s3fs/install.sh`,
+ Uninstall: `bash /www/panel/scripts/s3fs/uninstall.sh`,
+ Update: `bash /www/panel/scripts/s3fs/update.sh`,
+}
+
+var PluginRsync = PanelPlugin{
+ Name: "Rsync",
+ Description: "Rsync 是一款提供快速增量文件传输的开源工具。",
+ Slug: "rsync",
+ Version: "3.2.7",
+ Requires: []string{},
+ Excludes: []string{},
+ Install: `bash /www/panel/scripts/rsync/install.sh`,
+ Uninstall: `bash /www/panel/scripts/rsync/uninstall.sh`,
+ Update: `bash /www/panel/scripts/rsync/install.sh`,
+}
+
+var PluginSupervisor = PanelPlugin{
+ Name: "Supervisor",
+ Description: "Supervisor 是一个客户端/服务器系统,允许用户监视和控制类 UNIX 操作系统上的多个进程。",
+ Slug: "supervisor",
+ Version: "4.2.5",
+ Requires: []string{},
+ Excludes: []string{},
+ Install: `bash /www/panel/scripts/supervisor/install.sh`,
+ Uninstall: `bash /www/panel/scripts/supervisor/uninstall.sh`,
+ Update: `bash /www/panel/scripts/supervisor/update.sh`,
+}
+
+var PluginFail2ban = PanelPlugin{
+ Name: "Fail2ban",
+ Description: "Fail2ban 扫描系统日志文件并从中找出多次尝试失败的IP地址,将该IP地址加入防火墙的拒绝访问列表中。",
+ Slug: "fail2ban",
+ Version: "1.0.0",
+ Requires: []string{},
+ Excludes: []string{},
+ Install: `bash /www/panel/scripts/fail2ban/install.sh`,
+ Uninstall: `bash /www/panel/scripts/fail2ban/uninstall.sh`,
+ Update: `bash /www/panel/scripts/fail2ban/update.sh`,
+}
+
+var PluginToolBox = PanelPlugin{
+ Name: "系统工具箱",
+ Description: "可视化调整一些常用的配置项,如 DNS、SWAP、时区等",
+ Slug: "toolbox",
+ Version: "1.0.0",
+ Requires: []string{},
+ Excludes: []string{},
+ Install: `panel writePlugin toolbox 1.0`,
+ Uninstall: `panel deletePlugin toolbox`,
+ Update: `panel writePlugin toolbox 1.0`,
+}
diff --git a/internal/plugins/fail2ban/fail2ban.go b/internal/plugins/fail2ban/fail2ban.go
deleted file mode 100644
index 2f6fbd4f..00000000
--- a/internal/plugins/fail2ban/fail2ban.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package fail2ban
-
-var (
- Name = "Fail2ban"
- Description = "Fail2ban 扫描系统日志文件并从中找出多次尝试失败的IP地址,将该IP地址加入防火墙的拒绝访问列表中。"
- Slug = "fail2ban"
- Version = "1.0.0"
- Requires = []string{}
- Excludes = []string{}
- Install = `bash /www/panel/scripts/fail2ban/install.sh`
- Uninstall = `bash /www/panel/scripts/fail2ban/uninstall.sh`
- Update = `bash /www/panel/scripts/fail2ban/update.sh`
-)
diff --git a/internal/plugins/mysql57/mysql57.go b/internal/plugins/mysql57/mysql57.go
deleted file mode 100644
index 9e1fa8c5..00000000
--- a/internal/plugins/mysql57/mysql57.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package mysql57
-
-var (
- Name = "MySQL-5.7"
- Description = "MySQL 是最流行的关系型数据库管理系统之一,Oracle 旗下产品。(已停止维护,不建议使用!预计 2025 年 12 月移除)"
- Slug = "mysql57"
- Version = "5.7.44"
- Requires = []string{}
- Excludes = []string{"mysql80"}
- Install = `bash /www/panel/scripts/mysql/install.sh 57`
- Uninstall = `bash /www/panel/scripts/mysql/uninstall.sh 57`
- Update = `bash /www/panel/scripts/mysql/update.sh 57`
-)
diff --git a/internal/plugins/mysql80/mysql80.go b/internal/plugins/mysql80/mysql80.go
deleted file mode 100644
index 9c3fae4c..00000000
--- a/internal/plugins/mysql80/mysql80.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package mysql80
-
-var (
- Name = "MySQL-8.0"
- Description = "MySQL 是最流行的关系型数据库管理系统之一,Oracle 旗下产品。(建议内存 > 2G 安装)"
- Slug = "mysql80"
- Version = "8.0.36"
- Requires = []string{}
- Excludes = []string{"mysql57"}
- Install = `bash /www/panel/scripts/mysql/install.sh 80`
- Uninstall = `bash /www/panel/scripts/mysql/uninstall.sh 80`
- Update = `bash /www/panel/scripts/mysql/update.sh 80`
-)
diff --git a/internal/plugins/openresty/openresty.go b/internal/plugins/openresty/openresty.go
deleted file mode 100644
index e83ae92d..00000000
--- a/internal/plugins/openresty/openresty.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package openresty
-
-var (
- Name = "OpenResty"
- Description = "OpenResty® 是一款基于 NGINX 和 LuaJIT 的 Web 平台。"
- Slug = "openresty"
- Version = "1.25.3.1"
- Requires = []string{}
- Excludes = []string{}
- Install = "bash /www/panel/scripts/openresty/install.sh"
- Uninstall = "bash /www/panel/scripts/openresty/uninstall.sh"
- Update = "bash /www/panel/scripts/openresty/install.sh"
-)
diff --git a/internal/plugins/php74/php74.go b/internal/plugins/php74/php74.go
deleted file mode 100644
index 7be11a4b..00000000
--- a/internal/plugins/php74/php74.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package php74
-
-var (
- Name = "PHP-7.4"
- Description = "PHP 是世界上最好的语言!(已停止维护,不建议使用!预计 2024 年 12 月移除)"
- Slug = "php74"
- Version = "7.4.33"
- Requires = []string{}
- Excludes = []string{}
- Install = `bash /www/panel/scripts/php/install.sh 74`
- Uninstall = `bash /www/panel/scripts/php/uninstall.sh 74`
- Update = `bash /www/panel/scripts/php/install.sh 74`
-)
diff --git a/internal/plugins/php80/php80.go b/internal/plugins/php80/php80.go
deleted file mode 100644
index 42cb1e32..00000000
--- a/internal/plugins/php80/php80.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package php80
-
-var (
- Name = "PHP-8.0"
- Description = "PHP 是世界上最好的语言!(已停止维护,不建议使用!预计 2025 年 12 月移除)"
- Slug = "php80"
- Version = "8.0.30"
- Requires = []string{}
- Excludes = []string{}
- Install = `bash /www/panel/scripts/php/install.sh 80`
- Uninstall = `bash /www/panel/scripts/php/uninstall.sh 80`
- Update = `bash /www/panel/scripts/php/install.sh 80`
-)
diff --git a/internal/plugins/php81/php81.go b/internal/plugins/php81/php81.go
deleted file mode 100644
index cb9a1cc2..00000000
--- a/internal/plugins/php81/php81.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package php81
-
-var (
- Name = "PHP-8.1"
- Description = "PHP 是世界上最好的语言!"
- Slug = "php81"
- Version = "8.1.27"
- 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`
-)
diff --git a/internal/plugins/php82/php82.go b/internal/plugins/php82/php82.go
deleted file mode 100644
index 7896d6d5..00000000
--- a/internal/plugins/php82/php82.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package php82
-
-var (
- Name = "PHP-8.2"
- Description = "PHP 是世界上最好的语言!"
- Slug = "php82"
- Version = "8.2.16"
- 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`
-)
diff --git a/internal/plugins/php83/php83.go b/internal/plugins/php83/php83.go
deleted file mode 100644
index fed85990..00000000
--- a/internal/plugins/php83/php83.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package php83
-
-var (
- Name = "PHP-8.3"
- Description = "PHP 是世界上最好的语言!"
- Slug = "php83"
- Version = "8.3.3"
- Requires = []string{}
- Excludes = []string{}
- Install = `bash /www/panel/scripts/php/install.sh 83`
- Uninstall = `bash /www/panel/scripts/php/uninstall.sh 83`
- Update = `bash /www/panel/scripts/php/install.sh 83`
-)
diff --git a/internal/plugins/phpmyadmin/phpmyadmin.go b/internal/plugins/phpmyadmin/phpmyadmin.go
deleted file mode 100644
index fb07a9ce..00000000
--- a/internal/plugins/phpmyadmin/phpmyadmin.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package phpmyadmin
-
-var (
- Name = "phpMyAdmin"
- Description = "phpMyAdmin 是一个以 PHP 为基础,以 Web-Base 方式架构在网站主机上的 MySQL 数据库管理工具。"
- Slug = "phpmyadmin"
- Version = "5.2.1"
- Requires = []string{}
- Excludes = []string{}
- Install = `bash /www/panel/scripts/phpmyadmin/install.sh`
- Uninstall = `bash /www/panel/scripts/phpmyadmin/uninstall.sh`
- Update = `bash /www/panel/scripts/phpmyadmin/uninstall.sh && bash /www/panel/scripts/phpmyadmin/install.sh`
-)
diff --git a/internal/plugins/postgresql15/postgresql15.go b/internal/plugins/postgresql15/postgresql15.go
deleted file mode 100644
index 28f6efc4..00000000
--- a/internal/plugins/postgresql15/postgresql15.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package postgresql15
-
-var (
- Name = "PostgreSQL-15"
- Description = "PostgreSQL 是世界上最先进的开源关系数据库,在类似 BSD 与 MIT 许可的 PostgreSQL 许可下发行。"
- Slug = "postgresql15"
- Version = "15.6"
- Requires = []string{}
- Excludes = []string{"postgresql16"}
- Install = `bash /www/panel/scripts/postgresql/install.sh 15`
- Uninstall = `bash /www/panel/scripts/postgresql/uninstall.sh 15`
- Update = `bash /www/panel/scripts/postgresql/update.sh 15`
-)
diff --git a/internal/plugins/postgresql16/postgresql16.go b/internal/plugins/postgresql16/postgresql16.go
deleted file mode 100644
index 44a0ce69..00000000
--- a/internal/plugins/postgresql16/postgresql16.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package postgresql16
-
-var (
- Name = "PostgreSQL-16"
- Description = "PostgreSQL 是世界上最先进的开源关系数据库,在类似 BSD 与 MIT 许可的 PostgreSQL 许可下发行。"
- Slug = "postgresql16"
- Version = "16.2"
- Requires = []string{}
- Excludes = []string{"postgresql15"}
- Install = `bash /www/panel/scripts/postgresql/install.sh 16`
- Uninstall = `bash /www/panel/scripts/postgresql/uninstall.sh 16`
- Update = `bash /www/panel/scripts/postgresql/update.sh 16`
-)
diff --git a/internal/plugins/pureftpd/pureftpd.go b/internal/plugins/pureftpd/pureftpd.go
deleted file mode 100644
index 614e59c6..00000000
--- a/internal/plugins/pureftpd/pureftpd.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package pureftpd
-
-var (
- Name = "Pure-FTPd"
- Description = "Pure-Ftpd 是一个快速、高效、轻便、安全的 FTP 服务器,它以安全和配置简单为设计目标,支持虚拟主机,IPV6,PAM 等功能。"
- Slug = "pureftpd"
- Version = "1.0.50"
- Requires = []string{}
- Excludes = []string{}
- Install = `bash /www/panel/scripts/pureftpd/install.sh`
- Uninstall = `bash /www/panel/scripts/pureftpd/uninstall.sh`
- Update = `bash /www/panel/scripts/pureftpd/update.sh`
-)
diff --git a/internal/plugins/redis/redis.go b/internal/plugins/redis/redis.go
deleted file mode 100644
index 2f82c542..00000000
--- a/internal/plugins/redis/redis.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package redis
-
-var (
- Name = "Redis"
- Description = "Redis 是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。"
- Slug = "redis"
- Version = "7.2.4"
- Requires = []string{}
- Excludes = []string{}
- Install = `bash /www/panel/scripts/redis/install.sh`
- Uninstall = `bash /www/panel/scripts/redis/uninstall.sh`
- Update = `bash /www/panel/scripts/redis/update.sh`
-)
diff --git a/internal/plugins/rsync/rsync.go b/internal/plugins/rsync/rsync.go
deleted file mode 100644
index 5590b462..00000000
--- a/internal/plugins/rsync/rsync.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package rsync
-
-var (
- Name = "Rsync"
- Description = "Rsync 是一款提供快速增量文件传输的开源工具。"
- Slug = "rsync"
- Version = "3.2.7"
- Requires = []string{}
- Excludes = []string{}
- Install = `bash /www/panel/scripts/rsync/install.sh`
- Uninstall = `bash /www/panel/scripts/rsync/uninstall.sh`
- Update = `bash /www/panel/scripts/rsync/install.sh`
-)
diff --git a/internal/plugins/s3fs/s3fs.go b/internal/plugins/s3fs/s3fs.go
deleted file mode 100644
index cfc08ac4..00000000
--- a/internal/plugins/s3fs/s3fs.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package s3fs
-
-var (
- Name = "S3fs"
- Description = "S3fs 通过 FUSE 挂载兼容 S3 标准的存储桶,例如Amazon S3、阿里云OSS、腾讯云COS、七牛云Kodo等。"
- Slug = "s3fs"
- Version = "1.9"
- Requires = []string{}
- Excludes = []string{}
- Install = `bash /www/panel/scripts/s3fs/install.sh`
- Uninstall = `bash /www/panel/scripts/s3fs/uninstall.sh`
- Update = `bash /www/panel/scripts/s3fs/update.sh`
-)
diff --git a/internal/plugins/supervisor/supervisor.go b/internal/plugins/supervisor/supervisor.go
deleted file mode 100644
index 3cbf646c..00000000
--- a/internal/plugins/supervisor/supervisor.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package supervisor
-
-var (
- Name = "Supervisor"
- Description = "Supervisor 是一个客户端/服务器系统,允许用户监视和控制类 UNIX 操作系统上的多个进程。"
- Slug = "supervisor"
- Version = "4.2.5"
- Requires = []string{}
- Excludes = []string{}
- Install = `bash /www/panel/scripts/supervisor/install.sh`
- Uninstall = `bash /www/panel/scripts/supervisor/uninstall.sh`
- Update = `bash /www/panel/scripts/supervisor/update.sh`
-)
diff --git a/internal/plugins/toolbox/toolbox.go b/internal/plugins/toolbox/toolbox.go
deleted file mode 100644
index d717fd44..00000000
--- a/internal/plugins/toolbox/toolbox.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package toolbox
-
-var (
- Name = "系统工具箱"
- Description = "可视化调整一些常用的配置项,如 DNS、SWAP、时区 等"
- Slug = "toolbox"
- Version = "1.0"
- Requires = []string{}
- Excludes = []string{}
- Install = `panel writePlugin toolbox 1.0`
- Uninstall = `panel deletePlugin toolbox`
- Update = `panel writePlugin toolbox 1.0`
-)
diff --git a/internal/services/php.go b/internal/services/php.go
new file mode 100644
index 00000000..8a4ba54f
--- /dev/null
+++ b/internal/services/php.go
@@ -0,0 +1,368 @@
+package services
+
+import (
+ "errors"
+ "fmt"
+ "regexp"
+ "slices"
+ "strings"
+ "time"
+
+ "github.com/goravel/framework/facades"
+ "github.com/imroc/req/v3"
+ "github.com/spf13/cast"
+
+ "panel/app/models"
+ "panel/internal"
+ "panel/pkg/tools"
+)
+
+type PHPImpl struct {
+ version string
+}
+
+func NewPHPImpl(version uint) *PHPImpl {
+ return &PHPImpl{
+ version: cast.ToString(version),
+ }
+}
+
+func (r *PHPImpl) Status() (bool, error) {
+ return tools.ServiceStatus("php-fpm-" + r.version)
+}
+
+func (r *PHPImpl) Reload() error {
+ return tools.ServiceReload("php-fpm-" + r.version)
+}
+
+func (r *PHPImpl) Start() error {
+ return tools.ServiceStart("php-fpm-" + r.version)
+}
+
+func (r *PHPImpl) Stop() error {
+ return tools.ServiceStop("php-fpm-" + r.version)
+}
+
+func (r *PHPImpl) Restart() error {
+ return tools.ServiceRestart("php-fpm-" + r.version)
+}
+
+func (r *PHPImpl) GetConfig() (string, error) {
+ return tools.Read("/www/server/php/" + r.version + "/etc/php.ini")
+}
+
+func (r *PHPImpl) SaveConfig(config string) error {
+ if err := tools.Write("/www/server/php/"+r.version+"/etc/php.ini", config, 0644); err != nil {
+ return err
+ }
+
+ return r.Reload()
+}
+
+func (r *PHPImpl) GetFPMConfig() (string, error) {
+ return tools.Read("/www/server/php/" + r.version + "/etc/php-fpm.conf")
+}
+
+func (r *PHPImpl) SaveFPMConfig(config string) error {
+ if err := tools.Write("/www/server/php/"+r.version+"/etc/php-fpm.conf", config, 0644); err != nil {
+ return err
+ }
+
+ return r.Reload()
+}
+
+func (r *PHPImpl) Load() ([]internal.NV, error) {
+ client := req.C().SetTimeout(10 * time.Second)
+ resp, err := client.R().Get("http://127.0.0.1/phpfpm_status/" + r.version)
+ if err != nil || !resp.IsSuccessState() {
+ return nil, errors.New("获取 PHP-" + r.version + " 运行状态失败")
+ }
+
+ 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"}
+
+ data := make([]internal.NV, 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])
+ }
+ }
+
+ return data, nil
+}
+
+func (r *PHPImpl) GetErrorLog() (string, error) {
+ return tools.Exec("tail -n 500 /www/server/php/" + r.version + "/var/log/php-fpm.log")
+}
+
+func (r *PHPImpl) GetSlowLog() (string, error) {
+ return tools.Exec("tail -n 500 /www/server/php/" + r.version + "/var/log/slow.log")
+}
+
+func (r *PHPImpl) ClearErrorLog() error {
+ if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/php-fpm.log"); err != nil {
+ return errors.New(out)
+ }
+
+ return r.Reload()
+}
+
+func (r *PHPImpl) ClearSlowLog() error {
+ if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/slow.log"); err != nil {
+ return errors.New(out)
+ }
+
+ return nil
+}
+
+func (r *PHPImpl) GetExtensions() ([]internal.PHPExtension, error) {
+ extensions := []internal.PHPExtension{
+ {
+ Name: "fileinfo",
+ Slug: "fileinfo",
+ Description: "Fileinfo 是一个用于识别文件类型的库。",
+ Installed: false,
+ },
+ {
+ Name: "OPcache",
+ Slug: "Zend OPcache",
+ Description: "OPcache 通过将 PHP 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能,存储预编译字节码可以省去每次加载和解析 PHP 脚本的开销。",
+ Installed: false,
+ },
+ {
+ Name: "PhpRedis",
+ Slug: "redis",
+ Description: "PhpRedis 是一个用 C 语言编写的 PHP 模块,用来连接并操作 Redis 数据库上的数据。",
+ Installed: false,
+ },
+ {
+ Name: "ImageMagick",
+ Slug: "imagick",
+ Description: "ImageMagick 是一个免费的创建、编辑、合成图片的软件。",
+ Installed: false,
+ },
+ {
+ Name: "exif",
+ Slug: "exif",
+ Description: "通过 exif 扩展,你可以操作图像元数据。",
+ Installed: false,
+ },
+ {
+ Name: "pdo_pgsql",
+ Slug: "pdo_pgsql",
+ Description: "(需先安装PostgreSQL)pdo_pgsql 是一个驱动程序,它实现了 PHP 数据对象(PDO)接口以启用从 PHP 到 PostgreSQL 数据库的访问。",
+ Installed: false,
+ },
+ {
+ Name: "imap",
+ Slug: "imap",
+ Description: "IMAP 扩展允许 PHP 读取、搜索、删除、下载和管理邮件。",
+ Installed: false,
+ },
+ {
+ Name: "zip",
+ Slug: "zip",
+ Description: "Zip 是一个用于处理 ZIP 文件的库。",
+ Installed: false,
+ },
+ {
+ Name: "bz2",
+ Slug: "bz2",
+ Description: "Bzip2 是一个用于压缩和解压缩文件的库。",
+ Installed: false,
+ },
+ {
+ Name: "readline",
+ Slug: "readline",
+ Description: "Readline 是一个库,它提供了一种用于处理文本的接口。",
+ Installed: false,
+ },
+ {
+ Name: "snmp",
+ Slug: "snmp",
+ Description: "SNMP 是一种用于网络管理的协议。",
+ Installed: false,
+ },
+ {
+ Name: "ldap",
+ Slug: "ldap",
+ Description: "LDAP 是一种用于访问目录服务的协议。",
+ },
+ {
+ Name: "enchant",
+ Slug: "enchant",
+ Description: "Enchant 是一个拼写检查库。",
+ Installed: false,
+ },
+ {
+ Name: "pspell",
+ Slug: "pspell",
+ Description: "Pspell 是一个拼写检查库。",
+ Installed: false,
+ },
+ {
+ Name: "calendar",
+ Slug: "calendar",
+ Description: "Calendar 是一个用于处理日期的库。",
+ Installed: false,
+ },
+ {
+ Name: "gmp",
+ Slug: "gmp",
+ Description: "GMP 是一个用于处理大整数的库。",
+ Installed: false,
+ },
+ {
+ Name: "sysvmsg",
+ Slug: "sysvmsg",
+ Description: "Sysvmsg 是一个用于处理 System V 消息队列的库。",
+ Installed: false,
+ },
+ {
+ Name: "sysvsem",
+ Slug: "sysvsem",
+ Description: "Sysvsem 是一个用于处理 System V 信号量的库。",
+ },
+ {
+ Name: "sysvshm",
+ Slug: "sysvshm",
+ Description: "Sysvshm 是一个用于处理 System V 共享内存的库。",
+ Installed: false,
+ },
+ {
+ Name: "xsl",
+ Slug: "xsl",
+ Description: "XSL 是一个用于处理 XML 文档的库。",
+ Installed: false,
+ },
+ {
+ Name: "intl",
+ Slug: "intl",
+ Description: "Intl 是一个用于处理国际化和本地化的库。",
+ Installed: false,
+ },
+ {
+ Name: "gettext",
+ Slug: "gettext",
+ Description: "Gettext 是一个用于处理多语言的库。",
+ Installed: false,
+ },
+ /*{
+ Name: "igbinary",
+ Slug: "igbinary",
+ Description: "Igbinary 是一个用于序列化和反序列化数据的库。",
+ Installed: false,
+ },
+ {
+ Name: "swoole",
+ Slug: "swoole",
+ Description: "Swoole 是一个用于构建高性能的异步并发服务器的 PHP 扩展。",
+ Installed: false,
+ },
+ {
+ Name: "swow",
+ Slug: "swow",
+ Description: "Swow 是一个用于构建高性能的异步并发服务器的 PHP 扩展。",
+ Installed: false,
+ },*/
+ }
+
+ if cast.ToUint(r.version) < 83 {
+ extensions = append(extensions, internal.PHPExtension{
+ Name: "ionCube",
+ Slug: "ionCube Loader",
+ Description: "ionCube 是一个专业级的 PHP 加密解密工具。",
+ Installed: false,
+ })
+ }
+
+ raw, err := tools.Exec("/www/server/php/" + r.version + "/bin/php -m")
+ if err != nil {
+ return extensions, err
+ }
+
+ extensionMap := make(map[string]*internal.PHPExtension)
+ for i := range extensions {
+ extensionMap[extensions[i].Slug] = &extensions[i]
+ }
+
+ rawExtensionList := strings.Split(raw, "\n")
+ for _, item := range rawExtensionList {
+ if ext, exists := extensionMap[item]; exists && !strings.Contains(item, "[") && item != "" {
+ ext.Installed = true
+ }
+ }
+
+ return extensions, nil
+}
+
+func (r *PHPImpl) InstallExtension(slug string) error {
+ if !r.checkExtension(slug) {
+ return errors.New("扩展不存在")
+ }
+
+ shell := fmt.Sprintf(`bash '/www/panel/scripts/php_extensions/%s.sh' install %s >> '/tmp/%s.log' 2>&1`, slug, r.version, slug)
+
+ officials := []string{"fileinfo", "exif", "imap", "pdo_pgsql", "zip", "bz2", "readline", "snmp", "ldap", "enchant", "pspell", "calendar", "gmp", "sysvmsg", "sysvsem", "sysvshm", "xsl", "intl", "gettext"}
+ if slices.Contains(officials, slug) {
+ shell = fmt.Sprintf(`bash '/www/panel/scripts/php_extensions/official.sh' install '%s' '%s' >> '/tmp/%s.log' 2>&1`, r.version, slug, slug)
+ }
+
+ var task models.Task
+ task.Name = "安装PHP-" + r.version + "扩展-" + slug
+ task.Status = models.TaskStatusWaiting
+ task.Shell = shell
+ task.Log = "/tmp/" + slug + ".log"
+ if err := facades.Orm().Query().Create(&task); err != nil {
+ return err
+ }
+
+ NewTaskImpl().Process(task.ID)
+ return nil
+}
+
+func (r *PHPImpl) UninstallExtension(slug string) error {
+ if !r.checkExtension(slug) {
+ return errors.New("扩展不存在")
+ }
+
+ shell := fmt.Sprintf(`bash '/www/panel/scripts/php_extensions/%s.sh' uninstall %s >> '/tmp/%s.log' 2>&1`, slug, r.version, slug)
+
+ officials := []string{"fileinfo", "exif", "imap", "pdo_pgsql", "zip", "bz2", "readline", "snmp", "ldap", "enchant", "pspell", "calendar", "gmp", "sysvmsg", "sysvsem", "sysvshm", "xsl", "intl", "gettext"}
+ if slices.Contains(officials, slug) {
+ shell = fmt.Sprintf(`bash '/www/panel/scripts/php_extensions/official.sh' uninstall '%s' '%s' >> '/tmp/%s.log' 2>&1`, r.version, slug, slug)
+ }
+
+ var task models.Task
+ task.Name = "卸载PHP-" + r.version + "扩展-" + slug
+ task.Status = models.TaskStatusWaiting
+ task.Shell = shell
+ task.Log = "/tmp/" + slug + ".log"
+ if err := facades.Orm().Query().Create(&task); err != nil {
+ return err
+ }
+
+ NewTaskImpl().Process(task.ID)
+ return nil
+}
+
+func (r *PHPImpl) checkExtension(slug string) bool {
+ extensions, err := r.GetExtensions()
+ if err != nil {
+ return false
+ }
+
+ for _, item := range extensions {
+ if item.Slug == slug {
+ return true
+ }
+ }
+
+ return false
+}
diff --git a/internal/services/plugin.go b/internal/services/plugin.go
index 29a91169..bba316ac 100644
--- a/internal/services/plugin.go
+++ b/internal/services/plugin.go
@@ -3,27 +3,9 @@ package services
import (
"github.com/goravel/framework/facades"
- "panel/internal"
"panel/app/models"
- "panel/internal/plugins/fail2ban"
- "panel/internal/plugins/mysql57"
- "panel/internal/plugins/mysql80"
- "panel/internal/plugins/openresty"
- "panel/internal/plugins/php74"
- "panel/internal/plugins/php80"
- "panel/internal/plugins/php81"
- "panel/internal/plugins/php82"
- "panel/internal/plugins/php83"
- "panel/internal/plugins/phpmyadmin"
- "panel/internal/plugins/postgresql15"
- "panel/internal/plugins/postgresql16"
- "panel/internal/plugins/pureftpd"
- "panel/internal/plugins/redis"
- "panel/internal/plugins/rsync"
- "panel/internal/plugins/s3fs"
- "panel/internal/plugins/supervisor"
- "panel/internal/plugins/toolbox"
+ "panel/internal"
)
type PluginImpl struct {
@@ -45,208 +27,28 @@ func (r *PluginImpl) AllInstalled() ([]models.Plugin, error) {
// All 获取所有插件
func (r *PluginImpl) All() []internal.PanelPlugin {
- var p []internal.PanelPlugin
+ var plugins = []internal.PanelPlugin{
+ internal.PluginOpenResty,
+ internal.PluginMySQL57,
+ internal.PluginMySQL80,
+ internal.PluginPostgreSQL15,
+ internal.PluginPostgreSQL16,
+ internal.PluginPHP74,
+ internal.PluginPHP80,
+ internal.PluginPHP81,
+ internal.PluginPHP82,
+ internal.PluginPHP83,
+ internal.PluginPHPMyAdmin,
+ internal.PluginPureFTPd,
+ internal.PluginRedis,
+ internal.PluginS3fs,
+ internal.PluginRsync,
+ internal.PluginSupervisor,
+ internal.PluginFail2ban,
+ internal.PluginToolBox,
+ }
- p = append(p, internal.PanelPlugin{
- Name: openresty.Name,
- Description: openresty.Description,
- Slug: openresty.Slug,
- Version: openresty.Version,
- Requires: openresty.Requires,
- Excludes: openresty.Excludes,
- Install: openresty.Install,
- Uninstall: openresty.Uninstall,
- Update: openresty.Update,
- })
- p = append(p, internal.PanelPlugin{
- Name: mysql57.Name,
- Description: mysql57.Description,
- Slug: mysql57.Slug,
- Version: mysql57.Version,
- Requires: mysql57.Requires,
- Excludes: mysql57.Excludes,
- Install: mysql57.Install,
- Uninstall: mysql57.Uninstall,
- Update: mysql57.Update,
- })
- p = append(p, internal.PanelPlugin{
- Name: mysql80.Name,
- Description: mysql80.Description,
- Slug: mysql80.Slug,
- Version: mysql80.Version,
- Requires: mysql80.Requires,
- Excludes: mysql80.Excludes,
- Install: mysql80.Install,
- Uninstall: mysql80.Uninstall,
- Update: mysql80.Update,
- })
- p = append(p, internal.PanelPlugin{
- Name: postgresql15.Name,
- Description: postgresql15.Description,
- Slug: postgresql15.Slug,
- Version: postgresql15.Version,
- Requires: postgresql15.Requires,
- Excludes: postgresql15.Excludes,
- Install: postgresql15.Install,
- Uninstall: postgresql15.Uninstall,
- Update: postgresql15.Update,
- })
- p = append(p, internal.PanelPlugin{
- Name: postgresql16.Name,
- Description: postgresql16.Description,
- Slug: postgresql16.Slug,
- Version: postgresql16.Version,
- Requires: postgresql16.Requires,
- Excludes: postgresql16.Excludes,
- Install: postgresql16.Install,
- Uninstall: postgresql16.Uninstall,
- Update: postgresql16.Update,
- })
- p = append(p, internal.PanelPlugin{
- Name: php74.Name,
- Description: php74.Description,
- Slug: php74.Slug,
- Version: php74.Version,
- Requires: php74.Requires,
- Excludes: php74.Excludes,
- Install: php74.Install,
- Uninstall: php74.Uninstall,
- Update: php74.Update,
- })
- p = append(p, internal.PanelPlugin{
- Name: php80.Name,
- Description: php80.Description,
- Slug: php80.Slug,
- Version: php80.Version,
- Requires: php80.Requires,
- Excludes: php80.Excludes,
- Install: php80.Install,
- Uninstall: php80.Uninstall,
- Update: php80.Update,
- })
- p = append(p, internal.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, internal.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, internal.PanelPlugin{
- Name: php83.Name,
- Description: php83.Description,
- Slug: php83.Slug,
- Version: php83.Version,
- Requires: php83.Requires,
- Excludes: php83.Excludes,
- Install: php83.Install,
- Uninstall: php83.Uninstall,
- Update: php83.Update,
- })
- p = append(p, internal.PanelPlugin{
- Name: phpmyadmin.Name,
- Description: phpmyadmin.Description,
- Slug: phpmyadmin.Slug,
- Version: phpmyadmin.Version,
- Requires: phpmyadmin.Requires,
- Excludes: phpmyadmin.Excludes,
- Install: phpmyadmin.Install,
- Uninstall: phpmyadmin.Uninstall,
- Update: phpmyadmin.Update,
- })
- p = append(p, internal.PanelPlugin{
- Name: pureftpd.Name,
- Description: pureftpd.Description,
- Slug: pureftpd.Slug,
- Version: pureftpd.Version,
- Requires: pureftpd.Requires,
- Excludes: pureftpd.Excludes,
- Install: pureftpd.Install,
- Uninstall: pureftpd.Uninstall,
- Update: pureftpd.Update,
- })
- p = append(p, internal.PanelPlugin{
- Name: redis.Name,
- Description: redis.Description,
- Slug: redis.Slug,
- Version: redis.Version,
- Requires: redis.Requires,
- Excludes: redis.Excludes,
- Install: redis.Install,
- Uninstall: redis.Uninstall,
- Update: redis.Update,
- })
- p = append(p, internal.PanelPlugin{
- Name: s3fs.Name,
- Description: s3fs.Description,
- Slug: s3fs.Slug,
- Version: s3fs.Version,
- Requires: s3fs.Requires,
- Excludes: s3fs.Excludes,
- Install: s3fs.Install,
- Uninstall: s3fs.Uninstall,
- Update: s3fs.Update,
- })
- p = append(p, internal.PanelPlugin{
- Name: supervisor.Name,
- Description: supervisor.Description,
- Slug: supervisor.Slug,
- Version: supervisor.Version,
- Requires: supervisor.Requires,
- Excludes: supervisor.Excludes,
- Install: supervisor.Install,
- Uninstall: supervisor.Uninstall,
- Update: supervisor.Update,
- })
- p = append(p, internal.PanelPlugin{
- Name: fail2ban.Name,
- Description: fail2ban.Description,
- Slug: fail2ban.Slug,
- Version: fail2ban.Version,
- Requires: fail2ban.Requires,
- Excludes: fail2ban.Excludes,
- Install: fail2ban.Install,
- Uninstall: fail2ban.Uninstall,
- Update: fail2ban.Update,
- })
- p = append(p, internal.PanelPlugin{
- Name: rsync.Name,
- Description: rsync.Description,
- Slug: rsync.Slug,
- Version: rsync.Version,
- Requires: rsync.Requires,
- Excludes: rsync.Excludes,
- Install: rsync.Install,
- Uninstall: rsync.Uninstall,
- Update: rsync.Update,
- })
- p = append(p, internal.PanelPlugin{
- Name: toolbox.Name,
- Description: toolbox.Description,
- Slug: toolbox.Slug,
- Version: toolbox.Version,
- Requires: toolbox.Requires,
- Excludes: toolbox.Excludes,
- Install: toolbox.Install,
- Uninstall: toolbox.Uninstall,
- Update: toolbox.Update,
- })
-
- return p
+ return plugins
}
// GetBySlug 根据slug获取插件
diff --git a/routes/plugin.go b/routes/plugin.go
index 4a14decc..20a1bd81 100644
--- a/routes/plugin.go
+++ b/routes/plugin.go
@@ -139,7 +139,7 @@ func Plugin() {
route.Post("users/password", postgresql16Controller.SetUserPassword)
})
r.Prefix("php74").Group(func(route route.Router) {
- php74Controller := plugins.NewPhp74Controller()
+ php74Controller := plugins.NewPHPController(74)
route.Get("status", php74Controller.Status)
route.Post("reload", php74Controller.Reload)
route.Post("start", php74Controller.Start)
@@ -157,7 +157,7 @@ func Plugin() {
route.Delete("extensions", php74Controller.UninstallExtension)
})
r.Prefix("php80").Group(func(route route.Router) {
- php80Controller := plugins.NewPhp80Controller()
+ php80Controller := plugins.NewPHPController(80)
route.Get("status", php80Controller.Status)
route.Post("reload", php80Controller.Reload)
route.Post("start", php80Controller.Start)
@@ -175,7 +175,7 @@ func Plugin() {
route.Delete("extensions", php80Controller.UninstallExtension)
})
r.Prefix("php81").Group(func(route route.Router) {
- php81Controller := plugins.NewPhp81Controller()
+ php81Controller := plugins.NewPHPController(81)
route.Get("status", php81Controller.Status)
route.Post("reload", php81Controller.Reload)
route.Post("start", php81Controller.Start)
@@ -193,7 +193,7 @@ func Plugin() {
route.Delete("extensions", php81Controller.UninstallExtension)
})
r.Prefix("php82").Group(func(route route.Router) {
- php82Controller := plugins.NewPhp82Controller()
+ php82Controller := plugins.NewPHPController(82)
route.Get("status", php82Controller.Status)
route.Post("reload", php82Controller.Reload)
route.Post("start", php82Controller.Start)
@@ -211,7 +211,7 @@ func Plugin() {
route.Delete("extensions", php82Controller.UninstallExtension)
})
r.Prefix("php83").Group(func(route route.Router) {
- php83Controller := plugins.NewPhp83Controller()
+ php83Controller := plugins.NewPHPController(83)
route.Get("status", php83Controller.Status)
route.Post("reload", php83Controller.Reload)
route.Post("start", php83Controller.Start)
diff --git a/scripts/php/install.sh b/scripts/php/install.sh
index b0c3b62c..73614505 100644
--- a/scripts/php/install.sh
+++ b/scripts/php/install.sh
@@ -122,9 +122,9 @@ fi
# 配置
cd src
if [ "${phpVersion}" == "81" ] || [ "${phpVersion}" == "82" ] || [ "${phpVersion}" == "83" ]; then
- ./configure --prefix=${phpPath} --with-config-file-path=${phpPath}/etc --enable-fpm --with-fpm-user=www --with-fpm-group=www --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-freetype --with-jpeg --with-zlib --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-sysvsem --with-curl --enable-mbregex --enable-mbstring --enable-intl --enable-pcntl --enable-ftp --enable-gd --with-openssl --with-mhash --enable-pcntl --enable-sockets --enable-soap --with-gettext --enable-fileinfo --enable-opcache --with-sodium --with-webp --with-avif
+ ./configure --prefix=${phpPath} --with-config-file-path=${phpPath}/etc --enable-fpm --with-fpm-user=www --with-fpm-group=www --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-freetype --with-jpeg --with-zlib --enable-xml --disable-rpath --enable-bcmath --enable-shmop --with-curl --enable-mbregex --enable-mbstring --enable-pcntl --enable-ftp --enable-gd --with-openssl --with-mhash --enable-pcntl --enable-sockets --enable-soap --with-gettext --enable-fileinfo --enable-opcache --with-sodium --with-webp --with-avif
else
- ./configure --prefix=${phpPath} --with-config-file-path=${phpPath}/etc --enable-fpm --with-fpm-user=www --with-fpm-group=www --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-freetype --with-jpeg --with-zlib --with-libxml-dir=/usr --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --enable-mbregex --enable-mbstring --enable-intl --enable-pcntl --enable-ftp --enable-gd --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-soap --with-gettext --enable-fileinfo --enable-opcache --with-sodium --with-webp
+ ./configure --prefix=${phpPath} --with-config-file-path=${phpPath}/etc --enable-fpm --with-fpm-user=www --with-fpm-group=www --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-freetype --with-jpeg --with-zlib --with-libxml-dir=/usr --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-inline-optimization --with-curl --enable-mbregex --enable-mbstring --enable-pcntl --enable-ftp --enable-gd --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-soap --with-gettext --enable-fileinfo --enable-opcache --with-sodium --with-webp
fi
# 编译安装
diff --git a/scripts/php_extensions/exif.sh b/scripts/php_extensions/exif.sh
deleted file mode 100644
index eb894906..00000000
--- a/scripts/php_extensions/exif.sh
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/bin/bash
-export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH
-
-: '
-Copyright (C) 2022 - now HaoZi Technology Co., Ltd.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published
-by the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see .
-'
-
-HR="+----------------------------------------------------"
-
-action="$1" # 操作
-phpVersion="$2" # PHP版本
-
-Install() {
- # 检查是否已经安装
- isInstall=$(cat /www/server/php/${phpVersion}/etc/php.ini | grep '^extension=exif$')
- if [ "${isInstall}" != "" ]; then
- echo -e $HR
- echo "PHP-${phpVersion} 已安装 exif"
- exit 1
- fi
-
- cd /www/server/php/${phpVersion}/src/ext/exif
- /www/server/php/${phpVersion}/bin/phpize
- ./configure --with-php-config=/www/server/php/${phpVersion}/bin/php-config
- make
- if [ "$?" != "0" ]; then
- echo -e $HR
- echo "PHP-${phpVersion} exif 编译失败"
- exit 1
- fi
- make install
- if [ "$?" != "0" ]; then
- echo -e $HR
- echo "PHP-${phpVersion} exif 安装失败"
- exit 1
- fi
-
- sed -i '/;haozi/a\extension=exif' /www/server/php/${phpVersion}/etc/php.ini
-
- # 重载PHP
- systemctl reload php-fpm-${phpVersion}.service
- echo -e $HR
- echo "PHP-${phpVersion} exif 安装成功"
-}
-
-Uninstall() {
- # 检查是否已经安装
- isInstall=$(cat /www/server/php/${phpVersion}/etc/php.ini | grep '^extension=exif$')
- if [ "${isInstall}" == "" ]; then
- echo -e $HR
- echo "PHP-${phpVersion} 未安装 exif"
- exit 1
- fi
-
- sed -i '/extension=exif/d' /www/server/php/${phpVersion}/etc/php.ini
-
- # 重载PHP
- systemctl reload php-fpm-${phpVersion}.service
- echo -e $HR
- echo "PHP-${phpVersion} exif 卸载成功"
-}
-
-if [ "$action" == 'install' ]; then
- Install
-fi
-if [ "$action" == 'uninstall' ]; then
- Uninstall
-fi
diff --git a/scripts/php_extensions/official.sh b/scripts/php_extensions/official.sh
new file mode 100644
index 00000000..3d624e6a
--- /dev/null
+++ b/scripts/php_extensions/official.sh
@@ -0,0 +1,162 @@
+#!/bin/bash
+export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH
+
+: '
+Copyright (C) 2022 - now HaoZi Technology Co., Ltd.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published
+by the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+'
+
+HR="+----------------------------------------------------"
+OS=$(source /etc/os-release && { [[ "$ID" == "debian" ]] && echo "debian"; } || { [[ "$ID" == "centos" ]] || [[ "$ID" == "rhel" ]] || [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]] && echo "centos"; } || echo "unknown")
+
+action="$1" # 操作
+phpVersion="$2" # PHP版本
+extensionName="$3" # 扩展名称
+addArgs="" # 附加参数
+
+Install() {
+ # 检查是否已经安装
+ isInstall=$(cat /www/server/php/${phpVersion}/etc/php.ini | grep "^extension=${extensionName}$")
+ if [ "${isInstall}" != "" ]; then
+ echo -e $HR
+ echo "PHP-${phpVersion} 已安装 ${extensionName}"
+ exit 1
+ fi
+
+ # 安装依赖
+ if [ "${extensionName}" == "snmp" ]; then
+ if [ "${OS}" == "centos" ]; then
+ dnf install -y net-snmp-devel
+ elif [ "${OS}" == "debian" ]; then
+ apt-get install -y libsnmp-dev
+ fi
+ fi
+ if [ "${extensionName}" == "ldap" ]; then
+ if [ "${OS}" == "centos" ]; then
+ dnf install -y openldap-devel
+ ln -sf /usr/lib64/libldap* /usr/lib
+ elif [ "${OS}" == "debian" ]; then
+ apt-get install -y libldap2-dev
+ ln -sf /usr/lib/x86_64-linux-gnu/libldap* /usr/lib
+ fi
+ fi
+ if [ "${extensionName}" == "imap" ]; then
+ if [ "${OS}" == "centos" ]; then
+ # RHEL 9 的仓库中没有 libc-client-devel,待考虑
+ dnf install -y libc-client-devel
+ elif [ "${OS}" == "debian" ]; then
+ apt-get install -y libc-client-dev
+ fi
+ addArgs="--with-imap --with-imap-ssl --with-kerberos"
+ fi
+ if [ "${extensionName}" == "enchant" ]; then
+ if [ "${OS}" == "centos" ]; then
+ dnf install -y enchant-devel
+ elif [ "${OS}" == "debian" ]; then
+ apt-get install -y libenchant-2-dev
+ fi
+ fi
+ if [ "${extensionName}" == "pspell" ]; then
+ if [ "${OS}" == "centos" ]; then
+ dnf install -y aspell-devel
+ elif [ "${OS}" == "debian" ]; then
+ apt-get install -y libpspell-dev
+ fi
+ fi
+ if [ "${extensionName}" == "gmp" ]; then
+ if [ "${OS}" == "centos" ]; then
+ dnf install -y gmp-devel
+ elif [ "${OS}" == "debian" ]; then
+ apt-get install -y libgmp-dev
+ fi
+ fi
+ if [ "${extensionName}" == "gettext" ]; then
+ if [ "${OS}" == "centos" ]; then
+ dnf install -y gettext-devel
+ elif [ "${OS}" == "debian" ]; then
+ apt-get install -y libgettextpo-dev
+ fi
+ fi
+ if [ "${extensionName}" == "bz2" ]; then
+ if [ "${OS}" == "centos" ]; then
+ dnf install -y bzip2-devel
+ elif [ "${OS}" == "debian" ]; then
+ apt-get install -y libbz2-dev
+ fi
+ fi
+ if [ "${extensionName}" == "zip" ]; then
+ if [ "${OS}" == "centos" ]; then
+ dnf install -y libzip-devel
+ elif [ "${OS}" == "debian" ]; then
+ apt-get install -y libzip-dev
+ fi
+ fi
+ if [ "${extensionName}" == "pdo_pgsql" ]; then
+ addArgs="--with-pdo-pgsql=/www/server/postgresql"
+ fi
+
+ # 安装扩展
+ if [ ! -d /www/server/php/${phpVersion}/src/ext/${extensionName} ]; then
+ echo -e $HR
+ echo "PHP-${phpVersion} ${extensionName} 源码不存在"
+ exit 1
+ fi
+ cd /www/server/php/${phpVersion}/src/ext/${extensionName}
+ /www/server/php/${phpVersion}/bin/phpize
+ ./configure --with-php-config=/www/server/php/${phpVersion}/bin/php-config ${addArgs}
+ make
+ if [ "$?" != "0" ]; then
+ echo -e $HR
+ echo "PHP-${phpVersion} ${extensionName} 编译失败"
+ exit 1
+ fi
+ make install
+ if [ "$?" != "0" ]; then
+ echo -e $HR
+ echo "PHP-${phpVersion} ${extensionName} 安装失败"
+ exit 1
+ fi
+
+ sed -i "/;haozi/a\extension=${extensionName}" /www/server/php/${phpVersion}/etc/php.ini
+
+ # 重载PHP
+ systemctl reload php-fpm-${phpVersion}.service
+ echo -e $HR
+ echo "PHP-${phpVersion} ${extensionName} 安装成功"
+}
+
+Uninstall() {
+ # 检查是否已经安装
+ isInstall=$(cat /www/server/php/${phpVersion}/etc/php.ini | grep "^extension=${extensionName}$")
+ if [ "${isInstall}" == "" ]; then
+ echo -e $HR
+ echo "PHP-${phpVersion} 未安装 ${extensionName}"
+ exit 1
+ fi
+
+ sed -i "/extension=${extensionName}/d" /www/server/php/${phpVersion}/etc/php.ini
+
+ # 重载PHP
+ systemctl reload php-fpm-${phpVersion}.service
+ echo -e $HR
+ echo "PHP-${phpVersion} ${extensionName} 卸载成功"
+}
+
+if [ "$action" == 'install' ]; then
+ Install
+fi
+if [ "$action" == 'uninstall' ]; then
+ Uninstall
+fi
diff --git a/scripts/php_extensions/pdo_pgsql.sh b/scripts/php_extensions/pdo_pgsql.sh
deleted file mode 100644
index 134a527a..00000000
--- a/scripts/php_extensions/pdo_pgsql.sh
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/bin/bash
-export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH
-
-: '
-Copyright (C) 2022 - now HaoZi Technology Co., Ltd.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published
-by the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see .
-'
-
-HR="+----------------------------------------------------"
-
-action="$1"
-phpVersion="$2"
-
-Install() {
- # 检查是否已经安装
- isInstall=$(cat /www/server/php/${phpVersion}/etc/php.ini | grep '^extension=pdo_pgsql$')
- if [ "${isInstall}" != "" ]; then
- echo -e $HR
- echo "PHP-${phpVersion} 已安装 pdo_pgsql"
- exit 1
- fi
-
- cd /www/server/php/${phpVersion}/src/ext/pdo_pgsql
- /www/server/php/${phpVersion}/bin/phpize
- ./configure --with-php-config=/www/server/php/${phpVersion}/bin/php-config --with-pdo-pgsql=/www/server/postgresql
- make
- if [ "$?" != "0" ]; then
- echo -e $HR
- echo "PHP-${phpVersion} pdo_pgsql 编译失败"
- exit 1
- fi
- make install
- if [ "$?" != "0" ]; then
- echo -e $HR
- echo "PHP-${phpVersion} pdo_pgsql 安装失败"
- exit 1
- fi
-
- sed -i '/;haozi/a\extension=pdo_pgsql' /www/server/php/${phpVersion}/etc/php.ini
-
- # 重载PHP
- systemctl reload php-fpm-${phpVersion}.service
- echo -e $HR
- echo "PHP-${phpVersion} pdo_pgsql 安装成功"
-}
-
-Uninstall() {
- # 检查是否已经安装
- isInstall=$(cat /www/server/php/${phpVersion}/etc/php.ini | grep '^extension=pdo_pgsql$')
- if [ "${isInstall}" == "" ]; then
- echo -e $HR
- echo "PHP-${phpVersion} 未安装 pdo_pgsql"
- exit 1
- fi
-
- sed -i '/extension=pdo_pgsql/d' /www/server/php/${phpVersion}/etc/php.ini
-
- # 重载PHP
- systemctl reload php-fpm-${phpVersion}.service
- echo -e $HR
- echo "PHP-${phpVersion} pdo_pgsql 卸载成功"
-}
-
-if [ "$action" == 'install' ]; then
- Install
-fi
-if [ "$action" == 'uninstall' ]; then
- Uninstall
-fi