go修改php的配置文件

14 篇文章 0 订阅
5 篇文章 0 订阅

功能说明

通过go修改或者新增PHP配置文件的配置项。支持修改和新增的配置的值为int、float、string、map(对应php中的一维数组和二维数组)
PHP配置格式文件如下:
在这里插入图片描述

小试牛刀

go类型检测:

 var etcd_value interface{} //必须设置为接口类型,才能进行断言
  etcd_value = "666.8"
   // etcd_value = map[string]string{"host": "192.168.5.222266", "port": "99", "username": "niubi", "password": "222jjjj"}
   switch v := etcd_value.(type) {
   case int:
       fmt.Println("整数", v)
   case string:
       fmt.Println("字符串", v)
   case float64:
       fmt.Println("字符串", v)
   case map[string]string:
       fmt.Println("哈希", v)
   }

用switch进行类型检测并转换为字符串

//识别value类型并转换为字符串
func GetChangeValue(etcd_value interface{}) (string, bool) {
	var str string
	var isStr bool
	switch v := etcd_value.(type) {
	case int:
		str = strconv.Itoa(v)
	case string:
		str = v
		isStr = true
	case bool:
		str = strconv.FormatBool(v) //返回"true"或"false"。
	case float64:
		str = strconv.FormatFloat(v, 'f', -1, 64) //float64转为string类型
	case map[string]string:
		str = ArrToStr(v)
	case map[string]map[string]string:
		str = MultiArrToStr(v)
	}
	return str, isStr
}
str = strconv.FormatFloat(v, 'f', -1, 64) //float64转为string类型
这里第三个参数代表保存的小数位数,-1代表保存所有
//go截取字符串:遵循左闭右开原则
func main() {
	word := "helloworld"
	find := strings.Index(word, "l")
	cut := word[0:find]    //截取字符串遵循左闭右开
	fmt.Println(find, cut) //输出 2 he
}

最终代码

package updateConf

import (
	"fmt"
	"io/ioutil"
	"log"
	"strconv"
	"strings"
)

const (
	keyHead       = "$"
	keyCut        = ";"
	KeyConnectVal = "="
)

//配置文件不包含return的
func ChangeConfV1(path string, change_key string, change_value string, isStr bool) {
	bytes, err := ioutil.ReadFile(path)
	if err != nil {
		log.Fatalln("err:", err)
	}
	content := string(bytes)
	var key_start, key_end, value_start, value_end, real_start_index int
	var key_name, key_value string
	find := content
	isFirst := true
	for {
		if isFirst {
			first_cut := strings.Index(find, keyCut)
			if key_start == -1 {
				break
			}
			first := find[:first_cut]
			key_start = strings.Index(first, keyHead)
			key_end = strings.Index(first, KeyConnectVal)
			key_name = first[key_start:key_end]
			key_name = strings.TrimSpace(key_name)
			find = find[key_end:]
			real_start_index += key_end
			// =和;之间是key的值
			value_start = strings.Index(first, KeyConnectVal)
			key_value = first[value_start+1:]
			// fmt.Printf("key_name=%s;key_value=%s\n", key_name, key_value)
			isFirst = false
		}
		// fmt.Println("real_start_index", real_start_index)
		//判断是否是要修改的key
		if key_name == change_key {
			replace_start := real_start_index + 1
			replace_end := real_start_index + len(key_value) + 1
			// fmt.Printf("real value:%s\n", content[replace_start:replace_end])
			//将原来的值替换为新值
			var b strings.Builder
			b.WriteString(content[:replace_start]) //不包括replace_start
			b.WriteString(" ")
			if isStr {
				b.WriteString("'") // 仅针对字符串
			}
			b.WriteString(change_value)
			if isStr {
				b.WriteString("'") // 仅针对字符串
			}
			// b.WriteString("'")
			b.WriteString(content[replace_end:]) //包括replace_end(这里应该是分号)
			new := b.String()
			fmt.Println(new)
			// 生成新文件
			err := ioutil.WriteFile("./config_new.php", []byte(new), 0777)
			if err != nil {
				log.Printf("write config file failed. err : %s\n", err)
			}
			log.Printf("update config success ! update key = %s\n", key_name)
			return //跳出整个程序
		}
		real_start_index = real_start_index + value_end - 1
		// real_start_index = real_start_index + value_end + 1
		//以;为分隔符。;后面的$为变量的开头
		index := strings.Index(find, keyCut)
		if index == -1 {
			break
		}
		// fmt.Println("index=", index)
		find = find[index:]
		real_start_index += index
		key_start = strings.Index(find, keyHead)
		//如果不包含引号的话,说明已经遍历到最后的配置项了
		if key_start == -1 {
			break
		}
		// find = find[key_start:]
		key_end = strings.Index(find, KeyConnectVal)
		key_name = find[key_start:key_end]
		key_name = strings.TrimSpace(key_name)
		// fmt.Printf("key_name=%s\n", key_name)
		find = find[key_end:]
		real_start_index += key_end
		// = 和 ; 之间是key的值
		value_start = strings.Index(find, KeyConnectVal)
		value_end = strings.Index(find, keyCut)
		find = find[value_start+1:]
		real_start_index = real_start_index + value_start + 1
		key_value = find[:value_end-1]
		//去除value左右的空格
		// key_value = strings.TrimSpace(key_value)
		// fmt.Printf("key_name=%s;key_value=%s\n", key_name, key_value)
		find = find[value_end-1:]
	}
	//执行到这里说明原来的配置文件没有匹配到key_name,需要新增配置项
	// 找到最后一个分号
	lastSlice := strings.LastIndex(content, ";")
	if lastSlice == -1 {
		return
	}
	start_part := content[:lastSlice+1]
	end_part := content[lastSlice+1:]
	fmt.Println("lastslice", lastSlice)
	var b strings.Builder
	b.WriteString(start_part)
	b.WriteString("\n")
	b.WriteString(change_key)
	b.WriteString(" = ")
	if isStr {
		b.WriteString("'") // 仅针对字符串
	}
	b.WriteString(change_value)
	if isStr {
		b.WriteString("'") // 仅针对字符串
	}
	b.WriteString(keyCut)
	b.WriteString(end_part)
	new := b.String()
	fmt.Println("new=", new)
	// 生成新文件
	err = ioutil.WriteFile("./config_new.php", []byte(new), 0777)
	if err != nil {
		log.Printf("write config file failed. err : %s\n", err)
	}
	log.Printf("update config success ! insert key = %s\n", key_name)
}

//将数组拼装成字符串(针对一维数组)
func ArrToStr(str map[string]string) string {
	var b strings.Builder
	b.WriteString("array(\n\t")
	for key, val := range str {
		b.WriteString("'")
		b.WriteString(key)
		b.WriteString("'")
		b.WriteString(" => ")
		b.WriteString("'")
		b.WriteString(val)
		b.WriteString("'")
		b.WriteString(",")
	}
	b.WriteString("\n)")
	arrstr := b.String()
	return arrstr
}

//将数组拼装成字符串(针对二维数组)
func MultiArrToStr(str map[string]map[string]string) string {
	var b strings.Builder
	b.WriteString("array(\n")
	for key, val := range str {
		b.WriteString("'")
		b.WriteString(key)
		b.WriteString("'")
		b.WriteString(" => ")
		b.WriteString("array(\n\t")
		for k, v := range val {
			b.WriteString("'")
			b.WriteString(k)
			b.WriteString("'")
			b.WriteString(" => ")
			b.WriteString("'")
			b.WriteString(v)
			b.WriteString("'")
			b.WriteString(",")
		}
		b.WriteString("\n)")
		b.WriteString(",\n")
	}
	b.WriteString(")")
	arrstr := b.String()
	return arrstr
}

//识别value类型并转换为字符串
func GetChangeValue(etcd_value interface{}) (string, bool) {
	var str string
	var isStr bool
	switch v := etcd_value.(type) {
	case int:
		str = strconv.Itoa(v)
	case string:
		str = v
		isStr = true
	case float64:
		str = strconv.FormatFloat(v, 'f', -1, 64) //float64转为string类型
	case map[string]string:
		str = ArrToStr(v)
	case map[string]map[string]string:
		str = MultiArrToStr(v)
	}
	return str, isStr
}


func main() {
	conf_path := "./config1.php"
	change_key := "$slaveofRedis"
	var etcd_value interface{} //必须设置为接口类型,才能进行断言
	//字符串
	// etcd_value = 333
	//一维数组
	// etcd_value = map[string]string{"host": "192.168.5.222266", "port": "99", "username": "niubi", "password": "222jjjj"}
	//二维数组
	etcd_value = map[string]map[string]string{
		"test1": {"name": "lcj", "age": "22"},
		"test2": {"type": "dddd", "hello": "hhhhhh"},
		"test3": {"type": "333", "hello": "22222"},
	}
	change_value, isStr := updateConf.GetChangeValue(etcd_value)
	fmt.Printf("v=%v\n", change_value)
	updateConf.ChangeConfV1(conf_path, change_key, change_value, isStr)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值