php常用函数go语言实现

 基础语法  2021-07-05  admin  2086  2816

php常用函数go语言实现

php2go —— 使用 Golang 实现 PHP 常用内置函数,目前已经实现了 140+ 函数。

// php2go functions    
package php2go    
import (    
	"archive/zip"    
	"bytes"    
	"crypto/md5"    
	"crypto/sha1"    
	"encoding/base64"    
	"encoding/binary"    
	"encoding/csv"    
	"encoding/hex"    
	"encoding/json"    
	"fmt"    
	"hash/crc32"    
	"html"    
	"io"    
	"io/ioutil"    
	"math"    
	"math/rand"    
	"net"    
	"net/url"    
	"os"    
	"os/exec"    
	"path/filepath"    
	"reflect"    
	"runtime"    
	"strconv"    
	"strings"    
	"syscall"    
	"time"    
	"unicode"    
	"unicode/utf8"    
)    
//////////// Date/Time Functions ////////////    
// Time time()    
func Time() int64 {    
	return time.Now().Unix()    
}    
// Strtotime strtotime()    
// Strtotime("02/01/2006 15:04:05", "02/01/2016 15:04:05") == 1451747045    
// Strtotime("3 04 PM", "8 41 PM") == -62167144740    
func Strtotime(format, strtime string) (int64, error) {    
	t, err := time.Parse(format, strtime)    
	if err != nil {    
		return 0, err    
	}    
	return t.Unix(), nil    
}    
// Date date()    
// Date("02/01/2006 15:04:05 PM", 1524799394)    
func Date(format string, timestamp int64) string {    
	return time.Unix(timestamp, 0).Format(format)    
}    
// Checkdate checkdate()    
// Validate a Gregorian date    
func Checkdate(month, day, year int) bool {    
	if month < 1 || month > 12 || day < 1 || day > 31 || year < 1 || year > 32767 {    
		return false    
	}    
	switch month {    
	case 4, 6, 9, 11:    
		if day > 30 {    
			return false    
		}    
	case 2:    
		// leap year    
		if year%4 == 0 && (year%100 != 0 || year%400 == 0) {    
			if day > 29 {    
				return false    
			}    
		} else if day > 28 {    
			return false    
		}    
	}    
	return true    
}    
// Sleep sleep()    
func Sleep(t int64) {    
	time.Sleep(time.Duration(t) * time.Second)    
}    
// Usleep usleep()    
func Usleep(t int64) {    
	time.Sleep(time.Duration(t) * time.Microsecond)    
}    
//////////// String Functions ////////////    
// Strpos strpos()    
func Strpos(haystack, needle string, offset int) int {    
	length := len(haystack)    
	if length == 0 || offset > length || -offset > length {    
		return -1    
	}    
	if offset < 0 {    
		offset += length    
	}    
	pos := strings.Index(haystack[offset:], needle)    
	if pos == -1 {    
		return -1    
	}    
	return pos + offset    
}    
// Stripos stripos()    
func Stripos(haystack, needle string, offset int) int {    
	length := len(haystack)    
	if length == 0 || offset > length || -offset > length {    
		return -1    
	}    
	haystack = haystack[offset:]    
	if offset < 0 {    
		offset += length    
	}    
	pos := strings.Index(strings.ToLower(haystack), strings.ToLower(needle))    
	if pos == -1 {    
		return -1    
	}    
	return pos + offset    
}    
// Strrpos strrpos()    
func Strrpos(haystack, needle string, offset int) int {    
	pos, length := 0, len(haystack)    
	if length == 0 || offset > length || -offset > length {    
		return -1    
	}    
	if offset < 0 {    
		haystack = haystack[:offset+length+1]    
	} else {    
		haystack = haystack[offset:]    
	}    
	pos = strings.LastIndex(haystack, needle)    
	if offset > 0 && pos != -1 {    
		pos += offset    
	}    
	return pos    
}    
// Strripos strripos()    
func Strripos(haystack, needle string, offset int) int {    
	pos, length := 0, len(haystack)    
	if length == 0 || offset > length || -offset > length {    
		return -1    
	}    
	if offset < 0 {    
		haystack = haystack[:offset+length+1]    
	} else {    
		haystack = haystack[offset:]    
	}    
	pos = strings.LastIndex(strings.ToLower(haystack), strings.ToLower(needle))    
	if offset > 0 && pos != -1 {    
		pos += offset    
	}    
	return pos    
}    
// StrReplace str_replace()    
func StrReplace(search, replace, subject string, count int) string {    
	return strings.Replace(subject, search, replace, count)    
}    
// Strtoupper strtoupper()    
func Strtoupper(str string) string {    
	return strings.ToUpper(str)    
}    
// Strtolower strtolower()    
func Strtolower(str string) string {    
	return strings.ToLower(str)    
}    
// Ucfirst ucfirst()    
func Ucfirst(str string) string {    
	for _, v := range str {    
		u := string(unicode.ToUpper(v))    
		return u + str[len(u):]    
	}    
	return ""    
}    
// Lcfirst lcfirst()    
func Lcfirst(str string) string {    
	for _, v := range str {    
		u := string(unicode.ToLower(v))    
		return u + str[len(u):]    
	}    
	return ""    
}    
// Ucwords ucwords()    
func Ucwords(str string) string {    
	return strings.Title(str)    
}    
// Substr substr()    
func Substr(str string, start uint, length int) string {    
	if start < 0 || length < -1 {    
		return str    
	}    
	switch {    
	case length == -1:    
		return str[start:]    
	case length == 0:    
		return ""    
	}    
	end := int(start) + length    
	if end > len(str) {    
		end = len(str)    
	}    
	return str[start:end]    
}    
// Strrev strrev()    
func Strrev(str string) string {    
	runes := []rune(str)    
	for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {    
		runes[i], runes[j] = runes[j], runes[i]    
	}    
	return string(runes)    
}    
// ParseStr parse_str()    
// f1=m&f2=n -> map[f1:m f2:n]    
// f[a]=m&f[b]=n -> map[f:map[a:m b:n]]    
// f[a][a]=m&f[a][b]=n -> map[f:map[a:map[a:m b:n]]]    
// f[]=m&f[]=n -> map[f:[m n]]    
// f[a][]=m&f[a][]=n -> map[f:map[a:[m n]]]    
// f[][]=m&f[][]=n -> map[f:[map[]]] // Currently does not support nested slice.    
// f=m&f[a]=n -> error // This is not the same as PHP.    
// a .[[b=c -> map[a___[b:c]    
func ParseStr(encodedString string, result map[string]interface{}) error {    
	// build nested map.    
	var build func(map[string]interface{}, []string, interface{}) error    
	build = func(result map[string]interface{}, keys []string, value interface{}) error {    
		length := len(keys)    
		// trim ',"    
		key := strings.Trim(keys[0], "'\"")    
		if length == 1 {    
			result[key] = value    
			return nil    
		}    
		// The end is slice. like f[], f[a][]    
		if keys[1] == "" && length == 2 {    
			// todo nested slice    
			if key == "" {    
				return nil    
			}    
			val, ok := result[key]    
			if !ok {    
				result[key] = []interface{}{value}    
				return nil    
			}    
			children, ok := val.([]interface{})    
			if !ok {    
				return fmt.Errorf("expected type '[]interface{}' for key '%s', but got '%T'", key, val)    
			}    
			result[key] = append(children, value)    
			return nil    
		}    
		// The end is slice + map. like f[][a]    
		if keys[1] == "" && length > 2 && keys[2] != "" {    
			val, ok := result[key]    
			if !ok {    
				result[key] = []interface{}{}    
				val = result[key]    
			}    
			children, ok := val.([]interface{})    
			if !ok {    
				return fmt.Errorf("expected type '[]interface{}' for key '%s', but got '%T'", key, val)    
			}    
			if l := len(children); l > 0 {    
				if child, ok := children[l-1].(map[string]interface{}); ok {    
					if _, ok := child[keys[2]]; !ok {    
						_ = build(child, keys[2:], value)    
						return nil    
					}    
				}    
			}    
			child := map[string]interface{}{}    
			_ = build(child, keys[2:], value)    
			result[key] = append(children, child)    
			return nil    
		}    
		// map. like f[a], f[a][b]    
		val, ok := result[key]    
		if !ok {    
			result[key] = map[string]interface{}{}    
			val = result[key]    
		}    
		children, ok := val.(map[string]interface{})    
		if !ok {    
			return fmt.Errorf("expected type 'map[string]interface{}' for key '%s', but got '%T'", key, val)    
		}    
		return build(children, keys[1:], value)    
	}    
	// split encodedString.    
	parts := strings.Split(encodedString, "&")    
	for _, part := range parts {    
		pos := strings.Index(part, "=")    
		if pos <= 0 {    
			continue    
		}    
		key, err := url.QueryUnescape(part[:pos])    
		if err != nil {    
			return err    
		}    
		for key[0] == ' ' {    
			key = key[1:]    
		}    
		if key == "" || key[0] == '[' {    
			continue    
		}    
		value, err := url.QueryUnescape(part[pos+1:])    
		if err != nil {    
			return err    
		}    
		// split into multiple keys    
		var keys []string    
		left := 0    
		for i, k := range key {    
			if k == '[' && left == 0 {    
				left = i    
			} else if k == ']' {    
				if left > 0 {    
					if len(keys) == 0 {    
						keys = append(keys, key[:left])    
					}    
					keys = append(keys, key[left+1:i])    
					left = 0    
					if i+1 < len(key) && key[i+1] != '[' {    
						break    
					}    
				}    
			}    
		}    
		if len(keys) == 0 {    
			keys = append(keys, key)    
		}    
		// first key    
		first := ""    
		for i, chr := range keys[0] {    
			if chr == ' ' || chr == '.' || chr == '[' {    
				first += "_"    
			} else {    
				first += string(chr)    
			}    
			if chr == '[' {    
				first += keys[0][i+1:]    
				break    
			}    
		}    
		keys[0] = first    
		// build nested map    
		if err := build(result, keys, value); err != nil {    
			return err    
		}    
	}    
	return nil    
}    
// NumberFormat number_format()    
// decimals: Sets the number of decimal points.    
// decPoint: Sets the separator for the decimal point.    
// thousandsSep: Sets the thousands separator.    
func NumberFormat(number float64, decimals uint, decPoint, thousandsSep string) string {    
	neg := false    
	if number < 0 {    
		number = -number    
		neg = true    
	}    
	dec := int(decimals)    
	// Will round off    
	str := fmt.Sprintf("%."+strconv.Itoa(dec)+"F", number)    
	prefix, suffix := "", ""    
	if dec > 0 {    
		prefix = str[:len(str)-(dec+1)]    
		suffix = str[len(str)-dec:]    
	} else {    
		prefix = str    
	}    
	sep := []byte(thousandsSep)    
	n, l1, l2 := 0, len(prefix), len(sep)    
	// thousands sep num    
	c := (l1 - 1) / 3    
	tmp := make([]byte, l2*c+l1)    
	pos := len(tmp) - 1    
	for i := l1 - 1; i >= 0; i, n, pos = i-1, n+1, pos-1 {    
		if l2 > 0 && n > 0 && n%3 == 0 {    
			for j := range sep {    
				tmp[pos] = sep[l2-j-1]    
				pos--    
			}    
		}    
		tmp[pos] = prefix[i]    
	}    
	s := string(tmp)    
	if dec > 0 {    
		s += decPoint + suffix    
	}    
	if neg {    
		s = "-" + s    
	}    
	return s    
}    
// ChunkSplit chunk_split()    
func ChunkSplit(body string, chunklen uint, end string) string {    
	if end == "" {    
		end = "\r\n"    
	}    
	runes, erunes := []rune(body), []rune(end)    
	l := uint(len(runes))    
	if l <= 1 || l < chunklen {    
		return body + end    
	}    
	ns := make([]rune, 0, len(runes)+len(erunes))    
	var i uint    
	for i = 0; i < l; i += chunklen {    
		if i+chunklen > l {    
			ns = append(ns, runes[i:]...)    
		} else {    
			ns = append(ns, runes[i:i+chunklen]...)    
		}    
		ns = append(ns, erunes...)    
	}    
	return string(ns)    
}    
// StrWordCount str_word_count()    
func StrWordCount(str string) []string {    
	return strings.Fields(str)    
}    
// Wordwrap wordwrap()    
func Wordwrap(str string, width uint, br string, cut bool) string {    
	strlen := len(str)    
	brlen := len(br)    
	linelen := int(width)    
	if strlen == 0 {    
		return ""    
	}    
	if brlen == 0 {    
		panic("break string cannot be empty")    
	}    
	if linelen == 0 && cut {    
		panic("can't force cut when width is zero")    
	}    
	current, laststart, lastspace := 0, 0, 0    
	var ns []byte    
	for current = 0; current < strlen; current++ {    
		if str[current] == br[0] && current+brlen < strlen && str[current:current+brlen] == br {    
			ns = append(ns, str[laststart:current+brlen]...)    
			current += brlen - 1    
			lastspace = current + 1    
			laststart = lastspace    
		} else if str[current] == ' ' {    
			if current-laststart >= linelen {    
				ns = append(ns, str[laststart:current]...)    
				ns = append(ns, br[:]...)    
				laststart = current + 1    
			}    
			lastspace = current    
		} else if current-laststart >= linelen && cut && laststart >= lastspace {    
			ns = append(ns, str[laststart:current]...)    
			ns = append(ns, br[:]...)    
			laststart = current    
			lastspace = current    
		} else if current-laststart >= linelen && laststart < lastspace {    
			ns = append(ns, str[laststart:lastspace]...)    
			ns = append(ns, br[:]...)    
			lastspace++    
			laststart = lastspace    
		}    
	}    
	if laststart != current {    
		ns = append(ns, str[laststart:current]...)    
	}    
	return string(ns)    
}    
// Strlen strlen()    
func Strlen(str string) int {    
	return len(str)    
}    
// MbStrlen mb_strlen()    
func MbStrlen(str string) int {    
	return utf8.RuneCountInString(str)    
}    
// StrRepeat str_repeat()    
func StrRepeat(input string, multiplier int) string {    
	return strings.Repeat(input, multiplier)    
}    
// Strstr strstr()    
func Strstr(haystack string, needle string) string {    
	if needle == "" {    
		return ""    
	}    
	idx := strings.Index(haystack, needle)    
	if idx == -1 {    
		return ""    
	}    
	return haystack[idx+len([]byte(needle))-1:]    
}    
// Strtr strtr()    
//    
// If the parameter length is 1, type is: map[string]string    
// Strtr("baab", map[string]string{"ab": "01"}) will return "ba01"    
// If the parameter length is 2, type is: string, string    
// Strtr("baab", "ab", "01") will return "1001", a => 0; b => 1.    
func Strtr(haystack string, params ...interface{}) string {    
	ac := len(params)    
	if ac == 1 {    
		pairs := params[0].(map[string]string)    
		length := len(pairs)    
		if length == 0 {    
			return haystack    
		}    
		oldnew := make([]string, length*2)    
		for o, n := range pairs {    
			if o == "" {    
				return haystack    
			}    
			oldnew = append(oldnew, o, n)    
		}    
		return strings.NewReplacer(oldnew...).Replace(haystack)    
	} else if ac == 2 {    
		from := params[0].(string)    
		to := params[1].(string)    
		trlen, lt := len(from), len(to)    
		if trlen > lt {    
			trlen = lt    
		}    
		if trlen == 0 {    
			return haystack    
		}    
		str := make([]uint8, len(haystack))    
		var xlat [256]uint8    
		var i int    
		var j uint8    
		if trlen == 1 {    
			for i = 0; i < len(haystack); i++ {    
				if haystack[i] == from[0] {    
					str[i] = to[0]    
				} else {    
					str[i] = haystack[i]    
				}    
			}    
			return string(str)    
		}    
		// trlen != 1    
		for {    
			xlat[j] = j    
			if j++; j == 0 {    
				break    
			}    
		}    
		for i = 0; i < trlen; i++ {    
			xlat[from[i]] = to[i]    
		}    
		for i = 0; i < len(haystack); i++ {    
			str[i] = xlat[haystack[i]]    
		}    
		return string(str)    
	}    
	return haystack    
}    
// StrShuffle str_shuffle()    
func StrShuffle(str string) string {    
	runes := []rune(str)    
	r := rand.New(rand.NewSource(time.Now().UnixNano()))    
	s := make([]rune, len(runes))    
	for i, v := range r.Perm(len(runes)) {    
		s[i] = runes[v]    
	}    
	return string(s)    
}    
// Trim trim()    
func Trim(str string, characterMask ...string) string {    
	if len(characterMask) == 0 {    
		return strings.TrimSpace(str)    
	}    
	return strings.Trim(str, characterMask[0])    
}    
// Ltrim ltrim()    
func Ltrim(str string, characterMask ...string) string {    
	if len(characterMask) == 0 {    
		return strings.TrimLeftFunc(str, unicode.IsSpace)    
	}    
	return strings.TrimLeft(str, characterMask[0])    
}    
// Rtrim rtrim()    
func Rtrim(str string, characterMask ...string) string {    
	if len(characterMask) == 0 {    
		return strings.TrimRightFunc(str, unicode.IsSpace)    
	}    
	return strings.TrimRight(str, characterMask[0])    
}    
// Explode explode()    
func Explode(delimiter, str string) []string {    
	return strings.Split(str, delimiter)    
}    
// Chr chr()    
func Chr(ascii int) string {    
	return string(ascii)    
}    
// Ord ord()    
func Ord(char string) int {    
	r, _ := utf8.DecodeRune([]byte(char))    
	return int(r)    
}    
// Nl2br nl2br()    
// \n\r, \r\n, \r, \n    
func Nl2br(str string, isXhtml bool) string {    
	r, n, runes := '\r', '\n', []rune(str)    
	var br []byte    
	if isXhtml {    
		br = []byte("<br />")    
	} else {    
		br = []byte("<br>")    
	}    
	skip := false    
	length := len(runes)    
	var buf bytes.Buffer    
	for i, v := range runes {    
		if skip {    
			skip = false    
			continue    
		}    
		switch v {    
		case n, r:    
			if (i+1 < length) && (v == r && runes[i+1] == n) || (v == n && runes[i+1] == r) {    
				buf.Write(br)    
				skip = true    
				continue    
			}    
			buf.Write(br)    
		default:    
			buf.WriteRune(v)    
		}    
	}    
	return buf.String()    
}    
// JSONDecode json_decode()    
func JSONDecode(data []byte, val interface{}) error {    
	return json.Unmarshal(data, val)    
}    
// JSONEncode json_encode()    
func JSONEncode(val interface{}) ([]byte, error) {    
	return json.Marshal(val)    
}    
// Addslashes addslashes()    
func Addslashes(str string) string {    
	var buf bytes.Buffer    
	for _, char := range str {    
		switch char {    
		case '\'', '"', '\\':    
			buf.WriteRune('\\')    
		}    
		buf.WriteRune(char)    
	}    
	return buf.String()    
}    
// Stripslashes stripslashes()    
func Stripslashes(str string) string {    
	var buf bytes.Buffer    
	l, skip := len(str), false    
	for i, char := range str {    
		if skip {    
			skip = false    
		} else if char == '\\' {    
			if i+1 < l && str[i+1] == '\\' {    
				skip = true    
			}    
			continue    
		}    
		buf.WriteRune(char)    
	}    
	return buf.String()    
}    
// Quotemeta quotemeta()    
func Quotemeta(str string) string {    
	var buf bytes.Buffer    
	for _, char := range str {    
		switch char {    
		case '.', '+', '\\', '(', '$', ')', '[', '^', ']', '*', '?':    
			buf.WriteRune('\\')    
		}    
		buf.WriteRune(char)    
	}    
	return buf.String()    
}    
// Htmlentities htmlentities()    
func Htmlentities(str string) string {    
	return html.EscapeString(str)    
}    
// HTMLEntityDecode html_entity_decode()    
func HTMLEntityDecode(str string) string {    
	return html.UnescapeString(str)    
}    
// Md5 md5()    
func Md5(str string) string {    
	hash := md5.New()    
	hash.Write([]byte(str))    
	return hex.EncodeToString(hash.Sum(nil))    
}    
// Md5File md5_file()    
func Md5File(path string) (string, error) {    
	data, err := ioutil.ReadFile(path)    
	if err != nil {    
		return "", err    
	}    
	hash := md5.New()    
	hash.Write([]byte(data))    
	return hex.EncodeToString(hash.Sum(nil)), nil    
}    
// Sha1 sha1()    
func Sha1(str string) string {    
	hash := sha1.New()    
	hash.Write([]byte(str))    
	return hex.EncodeToString(hash.Sum(nil))    
}    
// Sha1File sha1_file()    
func Sha1File(path string) (string, error) {    
	data, err := ioutil.ReadFile(path)    
	if err != nil {    
		return "", err    
	}    
	hash := sha1.New()    
	hash.Write([]byte(data))    
	return hex.EncodeToString(hash.Sum(nil)), nil    
}    
// Crc32 crc32()    
func Crc32(str string) uint32 {    
	return crc32.ChecksumIEEE([]byte(str))    
}    
// Levenshtein levenshtein()    
// costIns: Defines the cost of insertion.    
// costRep: Defines the cost of replacement.    
// costDel: Defines the cost of deletion.    
func Levenshtein(str1, str2 string, costIns, costRep, costDel int) int {    
	var maxLen = 255    
	l1 := len(str1)    
	l2 := len(str2)    
	if l1 == 0 {    
		return l2 * costIns    
	}    
	if l2 == 0 {    
		return l1 * costDel    
	}    
	if l1 > maxLen || l2 > maxLen {    
		return -1    
	}    
	p1 := make([]int, l2+1)    
	p2 := make([]int, l2+1)    
	var c0, c1, c2 int    
	var i1, i2 int    
	for i2 := 0; i2 <= l2; i2++ {    
		p1[i2] = i2 * costIns    
	}    
	for i1 = 0; i1 < l1; i1++ {    
		p2[0] = p1[0] + costDel    
		for i2 = 0; i2 < l2; i2++ {    
			if str1[i1] == str2[i2] {    
				c0 = p1[i2]    
			} else {    
				c0 = p1[i2] + costRep    
			}    
			c1 = p1[i2+1] + costDel    
			if c1 < c0 {    
				c0 = c1    
			}    
			c2 = p2[i2] + costIns    
			if c2 < c0 {    
				c0 = c2    
			}    
			p2[i2+1] = c0    
		}    
		tmp := p1    
		p1 = p2    
		p2 = tmp    
	}    
	c0 = p1[l2]    
	return c0    
}    
// SimilarText similar_text()    
func SimilarText(first, second string, percent *float64) int {    
	var similarText func(string, string, int, int) int    
	similarText = func(str1, str2 string, len1, len2 int) int {    
		var sum, max int    
		pos1, pos2 := 0, 0    
		// Find the longest segment of the same section in two strings    
		for i := 0; i < len1; i++ {    
			for j := 0; j < len2; j++ {    
				for l := 0; (i+l < len1) && (j+l < len2) && (str1[i+l] == str2[j+l]); l++ {    
					if l+1 > max {    
						max = l + 1    
						pos1 = i    
						pos2 = j    
					}    
				}    
			}    
		}    
		if sum = max; sum > 0 {    
			if pos1 > 0 && pos2 > 0 {    
				sum += similarText(str1, str2, pos1, pos2)    
			}    
			if (pos1+max < len1) && (pos2+max < len2) {    
				s1 := []byte(str1)    
				s2 := []byte(str2)    
				sum += similarText(string(s1[pos1+max:]), string(s2[pos2+max:]), len1-pos1-max, len2-pos2-max)    
			}    
		}    
		return sum    
	}    
	l1, l2 := len(first), len(second)    
	if l1+l2 == 0 {    
		return 0    
	}    
	sim := similarText(first, second, l1, l2)    
	if percent != nil {    
		*percent = float64(sim*200) / float64(l1+l2)    
	}    
	return sim    
}    
// Soundex soundex()    
// Calculate the soundex key of a string.    
func Soundex(str string) string {    
	if str == "" {    
		panic("str: cannot be an empty string")    
	}    
	table := [26]rune{    
		// A, B, C, D    
		'0', '1', '2', '3',    
		// E, F, G    
		'0', '1', '2',    
		// H    
		'0',    
		// I, J, K, L, M, N    
		'0', '2', '2', '4', '5', '5',    
		// O, P, Q, R, S, T    
		'0', '1', '2', '6', '2', '3',    
		// U, V    
		'0', '1',    
		// W, X    
		'0', '2',    
		// Y, Z    
		'0', '2',    
	}    
	last, code, small := -1, 0, 0    
	sd := make([]rune, 4)    
	// build soundex string    
	for i := 0; i < len(str) && small < 4; i++ {    
		// ToUpper    
		char := str[i]    
		if char < '\u007F' && 'a' <= char && char <= 'z' {    
			code = int(char - 'a' + 'A')    
		} else {    
			code = int(char)    
		}    
		if code >= 'A' && code <= 'Z' {    
			if small == 0 {    
				sd[small] = rune(code)    
				small++    
				last = int(table[code-'A'])    
			} else {    
				code = int(table[code-'A'])    
				if code != last {    
					if code != 0 {    
						sd[small] = rune(code)    
						small++    
					}    
					last = code    
				}    
			}    
		}    
	}    
	// pad with "0"    
	for ; small < 4; small++ {    
		sd[small] = '0'    
	}    
	return string(sd)    
}    
//////////// URL Functions ////////////    
// ParseURL parse_url()    
// Parse a URL and return its components    
// -1: all; 1: scheme; 2: host; 4: port; 8: user; 16: pass; 32: path; 64: query; 128: fragment    
func ParseURL(str string, component int) (map[string]string, error) {    
	u, err := url.Parse(str)    
	if err != nil {    
		return nil, err    
	}    
	if component == -1 {    
		component = 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128    
	}    
	var components = make(map[string]string)    
	if (component & 1) == 1 {    
		components["scheme"] = u.Scheme    
	}    
	if (component & 2) == 2 {    
		components["host"] = u.Hostname()    
	}    
	if (component & 4) == 4 {    
		components["port"] = u.Port()    
	}    
	if (component & 8) == 8 {    
		components["user"] = u.User.Username()    
	}    
	if (component & 16) == 16 {    
		components["pass"], _ = u.User.Password()    
	}    
	if (component & 32) == 32 {    
		components["path"] = u.Path    
	}    
	if (component & 64) == 64 {    
		components["query"] = u.RawQuery    
	}    
	if (component & 128) == 128 {    
		components["fragment"] = u.Fragment    
	}    
	return components, nil    
}    
// URLEncode urlencode()    
func URLEncode(str string) string {    
	return url.QueryEscape(str)    
}    
// URLDecode urldecode()    
func URLDecode(str string) (string, error) {    
	return url.QueryUnescape(str)    
}    
// Rawurlencode rawurlencode()    
func Rawurlencode(str string) string {    
	return strings.Replace(url.QueryEscape(str), "+", "%20", -1)    
}    
// Rawurldecode rawurldecode()    
func Rawurldecode(str string) (string, error) {    
	return url.QueryUnescape(strings.Replace(str, "%20", "+", -1))    
}    
// HTTPBuildQuery http_build_query()    
func HTTPBuildQuery(queryData url.Values) string {    
	return queryData.Encode()    
}    
// Base64Encode base64_encode()    
func Base64Encode(str string) string {    
	return base64.StdEncoding.EncodeToString([]byte(str))    
}    
// Base64Decode base64_decode()    
func Base64Decode(str string) (string, error) {    
	switch len(str) % 4 {    
	case 2:    
		str += "=="    
	case 3:    
		str += "="    
	}    
	data, err := base64.StdEncoding.DecodeString(str)    
	if err != nil {    
		return "", err    
	}    
	return string(data), nil    
}    
//////////// Array(Slice/Map) Functions ////////////    
// ArrayFill array_fill()    
func ArrayFill(startIndex int, num uint, value interface{}) map[int]interface{} {    
	m := make(map[int]interface{})    
	var i uint    
	for i = 0; i < num; i++ {    
		m[startIndex] = value    
		startIndex++    
	}    
	return m    
}    
// ArrayFlip array_flip()    
func ArrayFlip(m map[interface{}]interface{}) map[interface{}]interface{} {    
	n := make(map[interface{}]interface{})    
	for i, v := range m {    
		n[v] = i    
	}    
	return n    
}    
// ArrayKeys array_keys()    
func ArrayKeys(elements map[interface{}]interface{}) []interface{} {    
	i, keys := 0, make([]interface{}, len(elements))    
	for key := range elements {    
		keys[i] = key    
		i++    
	}    
	return keys    
}    
// ArrayValues array_values()    
func ArrayValues(elements map[interface{}]interface{}) []interface{} {    
	i, vals := 0, make([]interface{}, len(elements))    
	for _, val := range elements {    
		vals[i] = val    
		i++    
	}    
	return vals    
}    
// ArrayMerge array_merge()    
func ArrayMerge(ss ...[]interface{}) []interface{} {    
	n := 0    
	for _, v := range ss {    
		n += len(v)    
	}    
	s := make([]interface{}, 0, n)    
	for _, v := range ss {    
		s = append(s, v...)    
	}    
	return s    
}    
// ArrayChunk array_chunk()    
func ArrayChunk(s []interface{}, size int) [][]interface{} {    
	if size < 1 {    
		panic("size: cannot be less than 1")    
	}    
	length := len(s)    
	chunks := int(math.Ceil(float64(length) / float64(size)))    
	var n [][]interface{}    
	for i, end := 0, 0; chunks > 0; chunks-- {    
		end = (i + 1) * size    
		if end > length {    
			end = length    
		}    
		n = append(n, s[i*size:end])    
		i++    
	}    
	return n    
}    
// ArrayPad array_pad()    
func ArrayPad(s []interface{}, size int, val interface{}) []interface{} {    
	if size == 0 || (size > 0 && size < len(s)) || (size < 0 && size > -len(s)) {    
		return s    
	}    
	n := size    
	if size < 0 {    
		n = -size    
	}    
	n -= len(s)    
	tmp := make([]interface{}, n)    
	for i := 0; i < n; i++ {    
		tmp[i] = val    
	}    
	if size > 0 {    
		return append(s, tmp...)    
	}    
	return append(tmp, s...)    
}    
// ArraySlice array_slice()    
func ArraySlice(s []interface{}, offset, length uint) []interface{} {    
	if offset > uint(len(s)) {    
		panic("offset: the offset is less than the length of s")    
	}    
	end := offset + length    
	if end < uint(len(s)) {    
		return s[offset:end]    
	}    
	return s[offset:]    
}    
// ArrayRand array_rand()    
func ArrayRand(elements []interface{}) []interface{} {    
	r := rand.New(rand.NewSource(time.Now().UnixNano()))    
	n := make([]interface{}, len(elements))    
	for i, v := range r.Perm(len(elements)) {    
		n[i] = elements[v]    
	}    
	return n    
}    
// ArrayColumn array_column()    
func ArrayColumn(input map[string]map[string]interface{}, columnKey string) []interface{} {    
	columns := make([]interface{}, 0, len(input))    
	for _, val := range input {    
		if v, ok := val[columnKey]; ok {    
			columns = append(columns, v)    
		}    
	}    
	return columns    
}    
// ArrayPush array_push()    
// Push one or more elements onto the end of slice    
func ArrayPush(s *[]interface{}, elements ...interface{}) int {    
	*s = append(*s, elements...)    
	return len(*s)    
}    
// ArrayPop array_pop()    
// Pop the element off the end of slice    
func ArrayPop(s *[]interface{}) interface{} {    
	if len(*s) == 0 {    
		return nil    
	}    
	ep := len(*s) - 1    
	e := (*s)[ep]    
	*s = (*s)[:ep]    
	return e    
}    
// ArrayUnshift array_unshift()    
// Prepend one or more elements to the beginning of a slice    
func ArrayUnshift(s *[]interface{}, elements ...interface{}) int {    
	*s = append(elements, *s...)    
	return len(*s)    
}    
// ArrayShift array_shift()    
// Shift an element off the beginning of slice    
func ArrayShift(s *[]interface{}) interface{} {    
	if len(*s) == 0 {    
		return nil    
	}    
	f := (*s)[0]    
	*s = (*s)[1:]    
	return f    
}    
// ArrayKeyExists array_key_exists()    
func ArrayKeyExists(key interface{}, m map[interface{}]interface{}) bool {    
	_, ok := m[key]    
	return ok    
}    
// ArrayCombine array_combine()    
func ArrayCombine(s1, s2 []interface{}) map[interface{}]interface{} {    
	if len(s1) != len(s2) {    
		panic("the number of elements for each slice isn't equal")    
	}    
	m := make(map[interface{}]interface{}, len(s1))    
	for i, v := range s1 {    
		m[v] = s2[i]    
	}    
	return m    
}    
// ArrayReverse array_reverse()    
func ArrayReverse(s []interface{}) []interface{} {    
	for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {    
		s[i], s[j] = s[j], s[i]    
	}    
	return s    
}    
// Implode implode()    
func Implode(glue string, pieces []string) string {    
	var buf bytes.Buffer    
	l := len(pieces)    
	for _, str := range pieces {    
		buf.WriteString(str)    
		if l--; l > 0 {    
			buf.WriteString(glue)    
		}    
	}    
	return buf.String()    
}    
// InArray in_array()    
// haystack supported types: slice, array or map    
func InArray(needle interface{}, haystack interface{}) bool {    
	val := reflect.ValueOf(haystack)    
	switch val.Kind() {    
	case reflect.Slice, reflect.Array:    
		for i := 0; i < val.Len(); i++ {    
			if reflect.DeepEqual(needle, val.Index(i).Interface()) {    
				return true    
			}    
		}    
	case reflect.Map:    
		for _, k := range val.MapKeys() {    
			if reflect.DeepEqual(needle, val.MapIndex(k).Interface()) {    
				return true    
			}    
		}    
	default:    
		panic("haystack: haystack type muset be slice, array or map")    
	}    
	return false    
}    
//////////// Mathematical Functions ////////////    
// Abs abs()    
func Abs(number float64) float64 {    
	return math.Abs(number)    
}    
// Rand rand()    
// Range: [0, 2147483647]    
func Rand(min, max int) int {    
	if min > max {    
		panic("min: min cannot be greater than max")    
	}    
	// PHP: getrandmax()    
	if int31 := 1<<31 - 1; max > int31 {    
		panic("max: max can not be greater than " + strconv.Itoa(int31))    
	}    
	if min == max {    
		return min    
	}    
	r := rand.New(rand.NewSource(time.Now().UnixNano()))    
	return r.Intn(max+1-min) + min    
}    
// Round round()    
func Round(value float64) float64 {    
	return math.Floor(value + 0.5)    
}    
// Floor floor()    
func Floor(value float64) float64 {    
	return math.Floor(value)    
}    
// Ceil ceil()    
func Ceil(value float64) float64 {    
	return math.Ceil(value)    
}    
// Pi pi()    
func Pi() float64 {    
	return math.Pi    
}    
// Max max()    
func Max(nums ...float64) float64 {    
	if len(nums) < 2 {    
		panic("nums: the nums length is less than 2")    
	}    
	max := nums[0]    
	for i := 1; i < len(nums); i++ {    
		max = math.Max(max, nums[i])    
	}    
	return max    
}    
// Min min()    
func Min(nums ...float64) float64 {    
	if len(nums) < 2 {    
		panic("nums: the nums length is less than 2")    
	}    
	min := nums[0]    
	for i := 1; i < len(nums); i++ {    
		min = math.Min(min, nums[i])    
	}    
	return min    
}    
// Decbin decbin()    
func Decbin(number int64) string {    
	return strconv.FormatInt(number, 2)    
}    
// Bindec bindec()    
func Bindec(str string) (string, error) {    
	i, err := strconv.ParseInt(str, 2, 0)    
	if err != nil {    
		return "", err    
	}    
	return strconv.FormatInt(i, 10), nil    
}    
// Hex2bin hex2bin()    
func Hex2bin(data string) (string, error) {    
	i, err := strconv.ParseInt(data, 16, 0)    
	if err != nil {    
		return "", err    
	}    
	return strconv.FormatInt(i, 2), nil    
}    
// Bin2hex bin2hex()    
func Bin2hex(str string) (string, error) {    
	i, err := strconv.ParseInt(str, 2, 0)    
	if err != nil {    
		return "", err    
	}    
	return strconv.FormatInt(i, 16), nil    
}    
// Dechex dechex()    
func Dechex(number int64) string {    
	return strconv.FormatInt(number, 16)    
}    
// Hexdec hexdec()    
func Hexdec(str string) (int64, error) {    
	return strconv.ParseInt(str, 16, 0)    
}    
// Decoct decoct()    
func Decoct(number int64) string {    
	return strconv.FormatInt(number, 8)    
}    
// Octdec Octdec()    
func Octdec(str string) (int64, error) {    
	return strconv.ParseInt(str, 8, 0)    
}    
// BaseConvert base_convert()    
func BaseConvert(number string, frombase, tobase int) (string, error) {    
	i, err := strconv.ParseInt(number, frombase, 0)    
	if err != nil {    
		return "", err    
	}    
	return strconv.FormatInt(i, tobase), nil    
}    
// IsNan is_nan()    
func IsNan(val float64) bool {    
	return math.IsNaN(val)    
}    
//////////// Directory/Filesystem Functions ////////////    
// Stat stat()    
func Stat(filename string) (os.FileInfo, error) {    
	return os.Stat(filename)    
}    
// Pathinfo pathinfo()    
// -1: all; 1: dirname; 2: basename; 4: extension; 8: filename    
// Usage:    
// Pathinfo("/home/go/path/src/php2go/php2go.go", 1|2|4|8)    
func Pathinfo(path string, options int) map[string]string {    
	if options == -1 {    
		options = 1 | 2 | 4 | 8    
	}    
	info := make(map[string]string)    
	if (options & 1) == 1 {    
		info["dirname"] = filepath.Dir(path)    
	}    
	if (options & 2) == 2 {    
		info["basename"] = filepath.Base(path)    
	}    
	if ((options & 4) == 4) || ((options & 8) == 8) {    
		basename := ""    
		if (options & 2) == 2 {    
			basename, _ = info["basename"]    
		} else {    
			basename = filepath.Base(path)    
		}    
		p := strings.LastIndex(basename, ".")    
		filename, extension := "", ""    
		if p > 0 {    
			filename, extension = basename[:p], basename[p+1:]    
		} else if p == -1 {    
			filename = basename    
		} else if p == 0 {    
			extension = basename[p+1:]    
		}    
		if (options & 4) == 4 {    
			info["extension"] = extension    
		}    
		if (options & 8) == 8 {    
			info["filename"] = filename    
		}    
	}    
	return info    
}    
// FileExists file_exists()    
func FileExists(filename string) bool {    
	_, err := os.Stat(filename)    
	if err != nil && os.IsNotExist(err) {    
		return false    
	}    
	return true    
}    
// IsFile is_file()    
func IsFile(filename string) bool {    
	_, err := os.Stat(filename)    
	if err != nil && os.IsNotExist(err) {    
		return false    
	}    
	return true    
}    
// IsDir is_dir()    
func IsDir(filename string) (bool, error) {    
	fd, err := os.Stat(filename)    
	if err != nil {    
		return false, err    
	}    
	fm := fd.Mode()    
	return fm.IsDir(), nil    
}    
// FileSize filesize()    
func FileSize(filename string) (int64, error) {    
	info, err := os.Stat(filename)    
	if err != nil && os.IsNotExist(err) {    
		return 0, err    
	}    
	return info.Size(), nil    
}    
// FilePutContents file_put_contents()    
func FilePutContents(filename string, data string, mode os.FileMode) error {    
	return ioutil.WriteFile(filename, []byte(data), mode)    
}    
// FileGetContents file_get_contents()    
func FileGetContents(filename string) (string, error) {    
	data, err := ioutil.ReadFile(filename)    
	return string(data), err    
}    
// Unlink unlink()    
func Unlink(filename string) error {    
	return os.Remove(filename)    
}    
// Delete delete()    
func Delete(filename string) error {    
	return os.Remove(filename)    
}    
// Copy copy()    
func Copy(source, dest string) (bool, error) {    
	fd1, err := os.Open(source)    
	if err != nil {    
		return false, err    
	}    
	defer fd1.Close()    
	fd2, err := os.OpenFile(dest, os.O_WRONLY|os.O_CREATE, 0644)    
	if err != nil {    
		return false, err    
	}    
	defer fd2.Close()    
	_, e := io.Copy(fd2, fd1)    
	if e != nil {    
		return false, e    
	}    
	return true, nil    
}    
// IsReadable is_readable()    
func IsReadable(filename string) bool {    
	_, err := syscall.Open(filename, syscall.O_RDONLY, 0)    
	if err != nil {    
		return false    
	}    
	return true    
}    
// IsWriteable is_writeable()    
func IsWriteable(filename string) bool {    
	_, err := syscall.Open(filename, syscall.O_WRONLY, 0)    
	if err != nil {    
		return false    
	}    
	return true    
}    
// Rename rename()    
func Rename(oldname, newname string) error {    
	return os.Rename(oldname, newname)    
}    
// Touch touch()    
func Touch(filename string) (bool, error) {    
	fd, err := os.OpenFile(filename, os.O_RDONLY|os.O_CREATE, 0666)    
	if err != nil {    
		return false, err    
	}    
	fd.Close()    
	return true, nil    
}    
// Mkdir mkdir()    
func Mkdir(filename string, mode os.FileMode) error {    
	return os.Mkdir(filename, mode)    
}    
// Getcwd getcwd()    
func Getcwd() (string, error) {    
	dir, err := os.Getwd()    
	return dir, err    
}    
// Realpath realpath()    
func Realpath(path string) (string, error) {    
	return filepath.Abs(path)    
}    
// Basename basename()    
func Basename(path string) string {    
	return filepath.Base(path)    
}    
// Chmod chmod()    
func Chmod(filename string, mode os.FileMode) bool {    
	return os.Chmod(filename, mode) == nil    
}    
// Chown chown()    
func Chown(filename string, uid, gid int) bool {    
	return os.Chown(filename, uid, gid) == nil    
}    
// Fclose fclose()    
func Fclose(handle *os.File) error {    
	return handle.Close()    
}    
// Filemtime filemtime()    
func Filemtime(filename string) (int64, error) {    
	fd, err := os.Open(filename)    
	if err != nil {    
		return 0, err    
	}    
	defer fd.Close()    
	fileinfo, err := fd.Stat()    
	if err != nil {    
		return 0, err    
	}    
	return fileinfo.ModTime().Unix(), nil    
}    
// Fgetcsv fgetcsv()    
func Fgetcsv(handle *os.File, length int, delimiter rune) ([][]string, error) {    
	reader := csv.NewReader(handle)    
	reader.Comma = delimiter    
	// TODO length limit    
	return reader.ReadAll()    
}    
// Glob glob()    
func Glob(pattern string) ([]string, error) {    
	return filepath.Glob(pattern)    
}    
//////////// Variable handling Functions ////////////    
// Empty empty()    
func Empty(val interface{}) bool {    
	if val == nil {    
		return true    
	}    
	v := reflect.ValueOf(val)    
	switch v.Kind() {    
	case reflect.String, reflect.Array:    
		return v.Len() == 0    
	case reflect.Map, reflect.Slice:    
		return v.Len() == 0 || v.IsNil()    
	case reflect.Bool:    
		return !v.Bool()    
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:    
		return v.Int() == 0    
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:    
		return v.Uint() == 0    
	case reflect.Float32, reflect.Float64:    
		return v.Float() == 0    
	case reflect.Interface, reflect.Ptr:    
		return v.IsNil()    
	}    
	return reflect.DeepEqual(val, reflect.Zero(v.Type()).Interface())    
}    
// IsNumeric is_numeric()    
// Numeric strings consist of optional sign, any number of digits, optional decimal part and optional exponential part.    
// Thus +0123.45e6 is a valid numeric value.    
// In PHP hexadecimal (e.g. 0xf4c3b00c) is not supported, but IsNumeric is supported.    
func IsNumeric(val interface{}) bool {    
	switch val.(type) {    
	case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:    
		return true    
	case float32, float64, complex64, complex128:    
		return true    
	case string:    
		str := val.(string)    
		if str == "" {    
			return false    
		}    
		// Trim any whitespace    
		str = strings.TrimSpace(str)    
		if str[0] == '-' || str[0] == '+' {    
			if len(str) == 1 {    
				return false    
			}    
			str = str[1:]    
		}    
		// hex    
		if len(str) > 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X') {    
			for _, h := range str[2:] {    
				if !((h >= '0' && h <= '9') || (h >= 'a' && h <= 'f') || (h >= 'A' && h <= 'F')) {    
					return false    
				}    
			}    
			return true    
		}    
		// 0-9, Point, Scientific    
		p, s, l := 0, 0, len(str)    
		for i, v := range str {    
			if v == '.' { // Point    
				if p > 0 || s > 0 || i+1 == l {    
					return false    
				}    
				p = i    
			} else if v == 'e' || v == 'E' { // Scientific    
				if i == 0 || s > 0 || i+1 == l {    
					return false    
				}    
				s = i    
			} else if v < '0' || v > '9' {    
				return false    
			}    
		}    
		return true    
	}    
	return false    
}    
//////////// Program execution Functions ////////////    
// Exec exec()    
// returnVar, 0: succ; 1: fail    
// Return the last line from the result of the command.    
// command format eg:    
//   "ls -a"    
//   "/bin/bash -c \"ls -a\""    
func Exec(command string, output *[]string, returnVar *int) string {    
	q := rune(0)    
	parts := strings.FieldsFunc(command, func(r rune) bool {    
		switch {    
		case r == q:    
			q = rune(0)    
			return false    
		case q != rune(0):    
			return false    
		case unicode.In(r, unicode.Quotation_Mark):    
			q = r    
			return false    
		default:    
			return unicode.IsSpace(r)    
		}    
	})    
	// remove the " and ' on both sides    
	for i, v := range parts {    
		f, l := v[0], len(v)    
		if l >= 2 && (f == '"' || f == '\'') {    
			parts[i] = v[1 : l-1]    
		}    
	}    
	cmd := exec.Command(parts[0], parts[1:]...)    
	out, err := cmd.CombinedOutput()    
	if err != nil {    
		*returnVar = 1    
		return ""    
	}    
	*returnVar = 0    
	*output = strings.Split(strings.TrimRight(string(out), "\n"), "\n")    
	if l := len(*output); l > 0 {    
		return (*output)[l-1]    
	}    
	return ""    
}    
// System system()    
// returnVar, 0: succ; 1: fail    
// Returns the last line of the command output on success, and "" on failure.    
func System(command string, returnVar *int) string {    
	*returnVar = 0    
	var stdBuf bytes.Buffer    
	var err, err1, err2, err3 error    
	// split command    
	q := rune(0)    
	parts := strings.FieldsFunc(command, func(r rune) bool {    
		switch {    
		case r == q:    
			q = rune(0)    
			return false    
		case q != rune(0):    
			return false    
		case unicode.In(r, unicode.Quotation_Mark):    
			q = r    
			return false    
		default:    
			return unicode.IsSpace(r)    
		}    
	})    
	// remove the " and ' on both sides    
	for i, v := range parts {    
		f, l := v[0], len(v)    
		if l >= 2 && (f == '"' || f == '\'') {    
			parts[i] = v[1 : l-1]    
		}    
	}    
	cmd := exec.Command(parts[0], parts[1:]...)    
	stdoutIn, _ := cmd.StdoutPipe()    
	stderrIn, _ := cmd.StderrPipe()    
	stdout := io.MultiWriter(os.Stdout, &stdBuf)    
	stderr := io.MultiWriter(os.Stderr, &stdBuf)    
	err = cmd.Start()    
	if err != nil {    
		*returnVar = 1    
		return ""    
	}    
	go func() {    
		_, err1 = io.Copy(stdout, stdoutIn)    
	}()    
	go func() {    
		_, err2 = io.Copy(stderr, stderrIn)    
	}()    
	err3 = cmd.Wait()    
	if err1 != nil || err2 != nil || err3 != nil {    
		if err1 != nil {    
			fmt.Println(err1)    
		}    
		if err2 != nil {    
			fmt.Println(err2)    
		}    
		if err3 != nil {    
			fmt.Println(err3)    
		}    
		*returnVar = 1    
		return ""    
	}    
	if output := strings.TrimRight(stdBuf.String(), "\n"); output != "" {    
		pos := strings.LastIndex(output, "\n")    
		if pos == -1 {    
			return output    
		}    
		return output[pos+1:]    
	}    
	return ""    
}    
// Passthru passthru()    
// returnVar, 0: succ; 1: fail    
func Passthru(command string, returnVar *int) {    
	q := rune(0)    
	parts := strings.FieldsFunc(command, func(r rune) bool {    
		switch {    
		case r == q:    
			q = rune(0)    
			return false    
		case q != rune(0):    
			return false    
		case unicode.In(r, unicode.Quotation_Mark):    
			q = r    
			return false    
		default:    
			return unicode.IsSpace(r)    
		}    
	})    
	// remove the " and ' on both sides    
	for i, v := range parts {    
		f, l := v[0], len(v)    
		if l >= 2 && (f == '"' || f == '\'') {    
			parts[i] = v[1 : l-1]    
		}    
	}    
	cmd := exec.Command(parts[0], parts[1:]...)    
	cmd.Stdout = os.Stdout    
	cmd.Stderr = os.Stderr    
	err := cmd.Run()    
	if err != nil {    
		*returnVar = 1    
		fmt.Println(err)    
	} else {    
		*returnVar = 0    
	}    
}    
//////////// Network Functions ////////////    
// Gethostname gethostname()    
func Gethostname() (string, error) {    
	return os.Hostname()    
}    
// Gethostbyname gethostbyname()    
// Get the IPv4 address corresponding to a given Internet host name    
func Gethostbyname(hostname string) (string, error) {    
	ips, err := net.LookupIP(hostname)    
	if ips != nil {    
		for _, v := range ips {    
			if v.To4() != nil {    
				return v.String(), nil    
			}    
		}    
		return "", nil    
	}    
	return "", err    
}    
// Gethostbynamel gethostbynamel()    
// Get a list of IPv4 addresses corresponding to a given Internet host name    
func Gethostbynamel(hostname string) ([]string, error) {    
	ips, err := net.LookupIP(hostname)    
	if ips != nil {    
		var ipstrs []string    
		for _, v := range ips {    
			if v.To4() != nil {    
				ipstrs = append(ipstrs, v.String())    
			}    
		}    
		return ipstrs, nil    
	}    
	return nil, err    
}    
// Gethostbyaddr gethostbyaddr()    
// Get the Internet host name corresponding to a given IP address    
func Gethostbyaddr(ipAddress string) (string, error) {    
	names, err := net.LookupAddr(ipAddress)    
	if names != nil {    
		return strings.TrimRight(names[0], "."), nil    
	}    
	return "", err    
}    
// IP2long ip2long()    
// IPv4    
func IP2long(ipAddress string) uint32 {    
	ip := net.ParseIP(ipAddress)    
	if ip == nil {    
		return 0    
	}    
	return binary.BigEndian.Uint32(ip.To4())    
}    
// Long2ip long2ip()    
// IPv4    
func Long2ip(properAddress uint32) string {    
	ipByte := make([]byte, 4)    
	binary.BigEndian.PutUint32(ipByte, properAddress)    
	ip := net.IP(ipByte)    
	return ip.String()    
}    
//////////// Misc. Functions ////////////    
// Echo echo    
func Echo(args ...interface{}) {    
	fmt.Print(args...)    
}    
// Uniqid uniqid()    
func Uniqid(prefix string) string {    
	now := time.Now()    
	return fmt.Sprintf("%s%08x%05x", prefix, now.Unix(), now.UnixNano()%0x100000)    
}    
// Exit exit()    
func Exit(status int) {    
	os.Exit(status)    
}    
// Die die()    
func Die(status int) {    
	os.Exit(status)    
}    
// Getenv getenv()    
func Getenv(varname string) string {    
	return os.Getenv(varname)    
}    
// Putenv putenv()    
// The setting, like "FOO=BAR"    
func Putenv(setting string) error {    
	s := strings.Split(setting, "=")    
	if len(s) != 2 {    
		panic("setting: invalid")    
	}    
	return os.Setenv(s[0], s[1])    
}    
// MemoryGetUsage memory_get_usage()    
// return in bytes    
func MemoryGetUsage(realUsage bool) uint64 {    
	stat := new(runtime.MemStats)    
	runtime.ReadMemStats(stat)    
	return stat.Alloc    
}    
// VersionCompare version_compare()    
// The possible operators are: <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne respectively.    
// special version strings these are handled in the following order,    
// (any string not found) < dev < alpha = a < beta = b < RC = rc < # < pl = p    
// Usage:    
// VersionCompare("1.2.3-alpha", "1.2.3RC7", '>=')    
// VersionCompare("1.2.3-beta", "1.2.3pl", 'lt')    
// VersionCompare("1.1_dev", "1.2any", 'eq')    
func VersionCompare(version1, version2, operator string) bool {    
	var vcompare func(string, string) int    
	var canonicalize func(string) string    
	var special func(string, string) int    
	// version compare    
	vcompare = func(origV1, origV2 string) int {    
		if origV1 == "" || origV2 == "" {    
			if origV1 == "" && origV2 == "" {    
				return 0    
			}    
			if origV1 == "" {    
				return -1    
			}    
			return 1    
		}    
		ver1, ver2, compare := "", "", 0    
		if origV1[0] == '#' {    
			ver1 = origV1    
		} else {    
			ver1 = canonicalize(origV1)    
		}    
		if origV2[0] == '#' {    
			ver2 = origV2    
		} else {    
			ver2 = canonicalize(origV2)    
		}    
		n1, n2 := 0, 0    
		for {    
			p1, p2 := "", ""    
			n1 = strings.IndexByte(ver1, '.')    
			if n1 == -1 {    
				p1, ver1 = ver1[:], ""    
			} else {    
				p1, ver1 = ver1[:n1], ver1[n1+1:]    
			}    
			n2 = strings.IndexByte(ver2, '.')    
			if n2 == -1 {    
				p2, ver2 = ver2, ""    
			} else {    
				p2, ver2 = ver2[:n2], ver2[n2+1:]    
			}    
			if (p1[0] >= '0' && p1[0] <= '9') && (p2[0] >= '0' && p2[0] <= '9') { // all is digit    
				l1, _ := strconv.Atoi(p1)    
				l2, _ := strconv.Atoi(p2)    
				if l1 > l2 {    
					compare = 1    
				} else if l1 == l2 {    
					compare = 0    
				} else {    
					compare = -1    
				}    
			} else if !(p1[0] >= '0' && p1[0] <= '9') && !(p2[0] >= '0' && p2[0] <= '9') { // all digit    
				compare = special(p1, p2)    
			} else { // part is digit    
				if p1[0] >= '0' && p1[0] <= '9' { // is digit    
					compare = special("#N#", p2)    
				} else {    
					compare = special(p1, "#N#")    
				}    
			}    
			if compare != 0 || n1 == -1 || n2 == -1 {    
				break    
			}    
		}    
		if compare == 0 {    
			if ver1 != "" {    
				if ver1[0] >= '0' && ver1[0] <= '9' {    
					compare = 1    
				} else {    
					compare = vcompare(ver1, "#N#")    
				}    
			} else if ver2 != "" {    
				if ver2[0] >= '0' && ver2[0] <= '9' {    
					compare = -1    
				} else {    
					compare = vcompare("#N#", ver2)    
				}    
			}    
		}    
		return compare    
	}    
	// canonicalize    
	canonicalize = func(version string) string {    
		ver := []byte(version)    
		l := len(ver)    
		if l == 0 {    
			return ""    
		}    
		var buf = make([]byte, l*2)    
		j := 0    
		for i, v := range ver {    
			next := uint8(0)    
			if i+1 < l { // Have the next one    
				next = ver[i+1]    
			}    
			if v == '-' || v == '_' || v == '+' { // replace '-', '_', '+' to '.'    
				if j > 0 && buf[j-1] != '.' {    
					buf[j] = '.'    
					j++    
				}    
			} else if (next > 0) &&    
				(!(next >= '0' && next <= '9') && (v >= '0' && v <= '9')) ||    
				(!(v >= '0' && v <= '9') && (next >= '0' && next <= '9')) { // Insert '.' before and after a non-digit    
				buf[j] = v    
				j++    
				if v != '.' && next != '.' {    
					buf[j] = '.'    
					j++    
				}    
				continue    
			} else if !((v >= '0' && v <= '9') ||    
				(v >= 'a' && v <= 'z') || (v >= 'A' && v <= 'Z')) { // Non-letters and numbers    
				if j > 0 && buf[j-1] != '.' {    
					buf[j] = '.'    
					j++    
				}    
			} else {    
				buf[j] = v    
				j++    
			}    
		}    
		return string(buf[:j])    
	}    
	// compare special version forms    
	special = func(form1, form2 string) int {    
		found1, found2, len1, len2 := -1, -1, len(form1), len(form2)    
		// (Any string not found) < dev < alpha = a < beta = b < RC = rc < # < pl = p    
		forms := map[string]int{    
			"dev":   0,    
			"alpha": 1,    
			"a":     1,    
			"beta":  2,    
			"b":     2,    
			"RC":    3,    
			"rc":    3,    
			"#":     4,    
			"pl":    5,    
			"p":     5,    
		}    
		for name, order := range forms {    
			if len1 < len(name) {    
				continue    
			}    
			if strings.Compare(form1[:len(name)], name) == 0 {    
				found1 = order    
				break    
			}    
		}    
		for name, order := range forms {    
			if len2 < len(name) {    
				continue    
			}    
			if strings.Compare(form2[:len(name)], name) == 0 {    
				found2 = order    
				break    
			}    
		}    
		if found1 == found2 {    
			return 0    
		} else if found1 > found2 {    
			return 1    
		} else {    
			return -1    
		}    
	}    
	compare := vcompare(version1, version2)    
	switch operator {    
	case "<", "lt":    
		return compare == -1    
	case "<=", "le":    
		return compare != 1    
	case ">", "gt":    
		return compare == 1    
	case ">=", "ge":    
		return compare != -1    
	case "==", "=", "eq":    
		return compare == 0    
	case "!=", "<>", "ne":    
		return compare != 0    
	default:    
		panic("operator: invalid")    
	}    
}    
// ZipOpen zip_open()    
func ZipOpen(filename string) (*zip.ReadCloser, error) {    
	return zip.OpenReader(filename)    
}    
// Pack pack()    
func Pack(order binary.ByteOrder, data interface{}) (string, error) {    
	buf := new(bytes.Buffer)    
	err := binary.Write(buf, order, data)    
	if err != nil {    
		return "", err    
	}    
	return buf.String(), nil    
}    
// Unpack unpack()    
func Unpack(order binary.ByteOrder, data string) (interface{}, error) {    
	var result []byte    
	r := bytes.NewReader([]byte(data))    
	err := binary.Read(r, order, &result)    
	if err != nil {    
		return nil, err    
	}    
	return result, nil    
}    
// Ternary Ternary expression    
// max := Ternary(a > b, a, b).(int)    
func Ternary(condition bool, trueVal, falseVal interface{}) interface{} {    
	if condition {    
		return trueVal    
	}    
	return falseVal    
}

github: https://github.com/syyongx/php2go/

另一个实现: https://github.com/Echo-Mr-Pengw/go-to-php

如果文章对您有帮助,点击下方的广告,支持一下作者吧!

转载必须注明出处:

php常用函数go语言实现 —— code.cent123.com

相关推荐


linux 系统最简单的安装 go 开发环境步骤

1. 官网下载放在 /godev 目录https://golang.google.cn/dl/或wget https://dl.google.com/go/go1.22.2.linux-amd64.tar.gz或curl -O https://dl.google.com/go/go1.22.2.linux-386.tar.gz2. 解压tar -xvf go1.22.2.linux-amd64.t

go 生成密码 php的 password_hash go实现

packagemain import( &quot;fmt&quot; &quot;golang.org/x/crypto/bcrypt&quot; ) funcmain(){ hashedPassword:=passwordHash(&quot;123456&quot;) fmt.Println(hashedPassword) hashedPassword=

使用 govcl 开发桌面UI 在 Lazarus IDE 编译中报错

使用 govcl 开发桌面UI 在 Lazarus IDE 编译中报错go build -i -buildmode=exe -ldflags=&quot;-H windowsgui&quot; -tags=&quot;tempdll&quot; -o &quot;project1.exe&quot;flag provided but not defined: -iusage: go build [

go 实现php的 password_hash() 密码加密方法

go 实现php的 password_hash() 密码加密方法