Go library for PHP community with convenient functions
Via go get command:
go get github.com/arthurkushman/pgo
Imagine that you need to write Go code every day and also have a convenient functions in memory from PHP experience
For instance, to store Go code data in storage engines like rdbms, no-sql, key-value etc, you can use serialization functions to serialize Go code to string and unserialize it back from string to Go code:
m := make(map[int]string)
m[0] = "abc"
str, err := pgo.Serialize(m) // str -> "Dv+BBAEC/4IAAQQBDAAACf+CAAEAA2FiYw=="
unserMap := make(map[int]string)
err = pgo.Unserialize(str, &unserMap) // unserMap -> map[int]string{0: "abc"}
You can use date function with similar formatting for PHP e.g.:
dateStr := pgo.Date("Y-m-d H:i:s") // 2019-03-28 12:23:03
pgo.Date("j D, M") // 27 Wed, Mar
pgo.Date("Q") // 3 (of 1,2,3,4 quarters)
nowMicro := pgo.UnixMicro() // get current unix microseconds
nowMilli := pgo.UnixMilli() // get current unix milliseconds
// get current millis + 3ms
nowMillisPlusThree := pgo.Time(time.Now().Add(time.Millisecond * 3)).Milliseconds()
// get current microseconds + 7ÎĽs
nowMicroPlusSeven := pgo.Time(now.Add(time.Microsecond * 7)).Microseconds()
replace sub-strings with StrReplace:
subject := "The quick brown fox jumped over the lazy dog"
str, err := pgo.StrReplace([]string{"fox", "dog"}, []string{"cat", "elephant"}, subject)
// and if case-insensitive replace needed - pgo.StrIReplace([]string{"DOG", "QuiCK"}, []string{"fox", "slow"}, subject)
Building a http query string:
queryStr := pgo.HTTPBuildQuery(map[string]interface{}{
"foo": "bar",
"bar": "baz",
"s": []string{"1", "foo", "2", "bar", "3", "baz"},
"num": 123,
"bigNum": int64(1238873737737737373),
"amount": 623.937,
"isActive": true,
}) // amount=623.937&bar=baz&bigNum=1238873737737737373&foo=bar&isActive=true&num=123&s=1&s=foo&s=2&s=bar&s=3&s=baz
Strip tags with exclusion rules:
html := "<div>Lorem <span>ipsum dolor sit amet</span>, consectetur adipiscing elit, sed do eiusmod <a href=\"http://example.com\">tempor incididunt</a> ut labore <strong>et dolore</strong> magna aliqua.</div>"
str := html.StripTags(html, []string{"a", "span"}) // results in: "Lorem <span>ipsum dolor sit amet</span>, consectetur adipiscing elit, sed do eiusmod <a href=\"http://example.com\">tempor incididunt</a> ut labore et dolore magna aliqua."
UPD: As had been stated here - golang/go#22639
There is a very handy "stripTags" function in html/template, then guys from official team as fast as they got dislike on
their negative comment, closed the thread. That is why libs like pgo
is appearing and will be move forward/evolve,
bypassing strict rules that sometimes looking nonsence.
Read files with offset/limit:
content, err := pgo.FileGetContents("somefile.txt", 0, 1024)
reflexively write to files with:
n, err := pgo.FilePutContents("somefile.txt", strToWrite, pgo.FileAppend)
Read from context (via http(s)):
content, err := pgo.FileGetContents("http://google.com", pgo.NewContext())
Uploading files from web-forms to your server:
ctx := pgo.NewContext()
ctx.Req = YourReq
ctx.UploadMaxFileSize = 10 << 25
uploaded := ctx.MoveUploadedFile("foo", "/srv/images/pic123.png")
Checking for file existence
if pgo.FileExists("file1.txt") == true {
// do something with existent file
}
Check if it is file/dir/symlink
if pgo.IsFile("someFile.txt") {
// do something with file
}
if pgo.IsDir("someDir/") {
// do something with dir
}
if pgo.IsLink("someLink") {
// do somthing with symlink
}
Check if an array contains an element
pgo.InArray(3, []int{1, 2, 3}) // true
pgo.InArray("bar33", []string{"foo", "bar", "baz"}) // false
pgo.InArray(3.14159, []float64{33.12, 12.333, 3.14159, 78.4429}) // true
Split an array by chunks (with auto-tailing)
pgo.ArrayChunk([]int{1, 2, 3, 4, 5, 6, 7, 8}, 2) // [][]int{[]int{1, 2}, []int{3, 4}, []int{5, 6}, []int{7, 8}}
pgo.ArrayChunk([]string{"foo", "bar", "baz", "fizz", "buzz"}, 3) // [][]string{[]string{"foo", "bar", "baz"}, []string{"fizz", "buzz"}}
Create an array by using one array for keys and another for its values
pgo.ArrayCombine([]int{11, 32, 13, 14, 51, 46, 17, 88}, []string{"foo", "bar", "baz", "fizz", "buzz", "mazz", "freez", "lorum"})
/*
map[int]string{
11: "foo",
32: "bar",
13: "baz",
14: "fizz",
51: "buzz",
46: "mazz",
17: "freez",
88: "lorum",
}
*/
pgo.ArrayCombine([]string{"foo", "bar", "baz", "fizz", "buzz"}, []float64{11.32, 32.42, 13.246, 14.41, 51.98})
/*
map[string]float64{
"foo": 11.32,
"bar": 32.42,
"baz": 13.246,
"fizz": 14.41,
"buzz": 51.98,
}
*/
Count all the values of an array/slice
pgo.ArrayCountValues([]string{"foo", "bar", "foo", "baz", "bar", "bar"}) // map[string]int{"foo": 2, "bar": 3, "baz": 1}
pgo.ArrayCountValues([]float64{3.14159, 43.03, 8, 3.14159, 43.02, 8}) // map[float64]int{3.14159: 2, 8: 2, 43.03: 1, 43.02: 1}
Apply the callback to the elements of the given arrays
pgo.ArrayMap([]string{"foo", "bar", "baz"}, func (v string) string {
return strings.ToUpper(v)
}) // []string{"FOO", "BAR", "BAZ"}
pgo.ArrayMap([]float64{1, 2, 3, 4, 5}, func (v float64) float64 {
return math.Pow(v, 2)
}) // []float64{1, 4, 9, 16, 25}
filters elements of an array using a callback function
pgo.ArrayFilter([]float64{1, 2, 3, 4, 5}, func (v float64) bool {
return v > 2.718
}) // []float64{3, 4, 5}
returns the values in array1 that are not present in any of the other arrays
pgo.ArrayDiff([]string{"foo", "bar", "fizz", "baz"}, []string{"foo", "bar"}) // []string{"fizz", "baz"}
pgo.ArrayDiff([]int{3, 43, 8, 4, 9}, []int{3, 8, 9, 4}) // []int{43}
computes the difference of arrays by using a callback function for data comparison
pgo.ArrayUdiff(func (a interface{}, b interface{}) int {
if a.(string) > b.(string) {
return 1
} else if a.(string) < b.(string) {
return -1
}
return 0
}, []string{"foo", "bar", "fizz", "baz"}, []string{"foo", "bar"}) // []string{"fizz", "baz"}
pgo.ArrayUdiff(func (a interface{}, b interface{}) int {
if a.(int) > b.(int) {
return 1
} else if a.(int) < b.(int) {
return -1
}
return 0
}, []int{3, 43, 8, 4, 9}, []int{3, 8, 9, 4}) // []int{43}
calculate the sum of values in an array
pgo.ArraySum([]int{12, 54, 32, 12, 33}) // int: 143
computes the intersection of arrays
pgo.ArrayIntersect([]int{12, 54, 32, 12, 33}, []int{3, 12, 54, 9}, []int{12, 33, 9}) // []int{12, 54, 33}
pgo.ArrayIntersect([]string{"foo", "bar", "baz", "fizz", "bazz", "fizz", "fizz"}, []string{"bar", "fizz"}, []string{"foo", "bar", "hey"}) // []string{"foo", "bar", "fizz"}
finds minimum/maximum value from []T
res = pgo.ArrayMax([]int{3, 1, 2, 9}) // res == 9
res = pgo.ArrayMax([]float64{-3.12, -1.678, -2.01, -9.007}) // res == -1.678
res = pgo.ArrayMin([]int{3, 1, 2, 9}) // res == 1
res = pgo.ArrayMin([]float64{3.2, 1.0837, 2.123, 9.87}) // res == 1.0837
returns unique values form []T
res = pgo.ArrayUnique([]int{1, 2, 2, 3, 2, 4, 4}) // []int{1, 2, 3, 4}
res = pgo.ArrayUnique([]string{"foo", "bar", "foo", "bar"}) // []string{"bar", "foo"}
Note: order is not guaranteed
return all the values of map as a slice of values with corresponding type
res = pgo.ArrayValues(map[string]int{"a": 1, "b": 2, "c": 3}) // []int{1, 2, 3}
res = pgo.ArrayValues(map[int]float64{1: 123.33, 2: 22, 3: 123.33}) // []float64{22, 123.33, 123.33}
reverse slice passed as an argument
toReverse := []int{-3, 0, 4, 9, 13}
pgo.ArrayReverse(toReverse)
fmt.Println(toReverse) // []int{13, 9, 4, 0, -3}
creates an int slice of min to max range
pgo.Range(3, 9) // []int{3, 4, 5, 6, 7, 8, 9}
// If a step value is given, it will be used as the increment between elements in the sequence.
pgo.Range(-3, 7, 5) // []int{-3, 2, 7}
Compares two slices and returns true if they are equal, false otherwise (any type of slices support)
res, err := pgo.EqualSlices([]int{1, 2, 3}, []int{1, 2, 3}) // true
res, err := pgo.EqualSlices([]string{"foo"}, []string{"bar"}) // false
See more examples in *_test.go files.
// Some items and their priorities.
items := map[string]int{
"banana": 3, "apple": 2, "pear": 4, "peach": 1, "plum": 6,
}
// Create a Priority queue, put the items in it, and
// establish the Priority queue (heap) invariants.
pq := make(pgo.PriorityQueue, len(items))
i := 0
for value, priority := range items {
pq[i] = &pgo.Item{
Value: value,
Priority: priority,
Index: i,
}
i++
}
pq.Init()
// Insert a new item and then modify its Priority.
item := &pgo.Item{
Value: "orange",
Priority: 1,
}
pq.Push(item)
pq.Update(item, item.Value, 5)
item := pq.Pop().(*pgo.Item) // 06:plum
item := pq.Pop().(*pgo.Item) // 05:orange
item := pq.Pop().(*pgo.Item) // 04:pear
item := pq.Pop().(*pgo.Item) // 03:banana
// ...
long, _ := pgo.IP2long("176.59.34.117") // 2956665461
ip := pgo.Long2ip(2956665461) // "176.59.34.117"
isMx, mxs, _ := pgo.GetMxrr("google.com") // e.g.: true, n
rand := pgo.Rand(1, 100)
pgo.Md5("abc123") // e99a18c428cb38d5f260853678922e03
pgo.Sha1("abc123") // 6367c48dd193d56ea7b0baad25b19455e529f5ee
pgo.Sha2("abc123") // 6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090
hex, err := pgo.HashFile("sha1", "example.txt") // 6367c48dd193d56ea7b0baad25b19455e529f5ee
hmac := HashHmac("foo bar baz", "secret", sha256.New) // 9efc4f86917b454deae37c869521f88dee79305303fa2283df0b480e3cc8104c
IsValidMac("foo bar baz", hmac, "secret", sha256.New) // true/false
Supporters gratitude: