{"id":13786656,"url":"https://github.com/arthurkushman/pgo","last_synced_at":"2025-07-25T17:37:57.556Z","repository":{"id":34910056,"uuid":"163147649","full_name":"arthurkushman/pgo","owner":"arthurkushman","description":"Go library for PHP community with convenient functions","archived":false,"fork":false,"pushed_at":"2024-04-08T18:11:23.000Z","size":197,"stargazers_count":87,"open_issues_count":1,"forks_count":16,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-16T02:47:26.622Z","etag":null,"topics":["api","array","arrays","date","files","filter","filters","functions","go","golang","html","ip2long","map","maps","php","strings","striptags"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arthurkushman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-12-26T06:59:47.000Z","updated_at":"2025-03-05T01:28:15.000Z","dependencies_parsed_at":"2024-03-28T20:36:11.488Z","dependency_job_id":"149da416-f17a-444d-bac4-1e321d39e3c3","html_url":"https://github.com/arthurkushman/pgo","commit_stats":null,"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arthurkushman%2Fpgo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arthurkushman%2Fpgo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arthurkushman%2Fpgo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arthurkushman%2Fpgo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arthurkushman","download_url":"https://codeload.github.com/arthurkushman/pgo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243875125,"owners_count":20361952,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","array","arrays","date","files","filter","filters","functions","go","golang","html","ip2long","map","maps","php","strings","striptags"],"created_at":"2024-08-03T19:01:27.268Z","updated_at":"2025-03-16T13:31:18.574Z","avatar_url":"https://github.com/arthurkushman.png","language":"Go","funding_links":[],"categories":["工具库`可以提升效率的通用代码库和工具`","公用事业公司","Utilities","工具库","Utility"],"sub_categories":["查询语","实用程序/Miscellaneous","Utility/Miscellaneous","HTTP Clients","Fail injection"],"readme":"# pgo\n\nGo library for PHP community with convenient functions\n\n[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go)\n[![Go Report Card](https://goreportcard.com/badge/github.com/arthurkushman/pgo)](https://goreportcard.com/report/github.com/arthurkushman/pgo)\n[![Build and test](https://github.com/arthurkushman/pgo/workflows/Build%20and%20test/badge.svg)](https://github.com/arthurkushman/pgo/actions)\n[![codecov](https://codecov.io/gh/arthurkushman/pgo/branch/master/graph/badge.svg)](https://codecov.io/gh/arthurkushman/pgo)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n[![GoDoc](https://github.com/golang/gddo/blob/c782c79e0a3c3282dacdaaebeff9e6fd99cb2919/gddo-server/assets/status.svg)](https://godoc.org/github.com/arthurkushman/pgo)\n\n* [Installation](#user-content-installation)\n* [Core](#user-content-core)\n    * [Serialize/Unserialize](#user-content-serializeunserialize)\n* [Date](#user-content-date)\n    * [Milli/Micro](#user-content-millimicro)\n* [Strings](#user-content-strings)\n    * [StrReplace/StrIReplace](#user-content-strreplace)\n    * [HTTPBuildQuery](#user-content-httpbuildquery)\n    * [StripTags](#user-content-striptags)\n* [Files](#user-content-files)\n    * [FileGetContents](#user-content-filegetcontents)\n    * [FilePutContents](#user-content-fileputcontents)\n    * [MoveUploadedFile](#user-content-moveuploadedfile)\n    * [FileExists](#user-content-fileexists)\n    * [IsFile/IsDir/IsLink](#user-content-isfileisdirislink)\n* [Arrays](#user-content-arrays)\n    * [InArray](#user-content-inarray)\n    * [ArrayChunk](#user-content-arraychunk)\n    * [ArrayCombine](#user-content-arraycombine)\n    * [ArrayCountValues](#user-content-arraycountvalues)\n    * [ArrayMap](#user-content-arraymap)\n    * [ArrayFilter](#user-content-arrayfilter)\n    * [ArrayDiff](#user-content-arraydiff)\n    * [ArrayUdiff](#user-content-arrayudiff)\n    * [ArraySum](#user-content-arraysum)\n    * [ArrayIntersect](#user-content-arrayintersect)\n    * [ArrayMin/ArrayMax](#user-content-arrayminarraymax)\n    * [ArrayUnique](#user-content-arrayunique)\n    * [ArrayValues](#user-content-arrayvalues)\n    * [ArrayReverse](#user-content-arrayreverse)\n    * [Range](#user-content-range)\n    * [EqualSlices](#user-content-equalslices)\n* [Collections](#user-content-collections)\n    * [PriorityQueue](#user-content-priority-queue)\n* [Network](#user-content-network)\n    * [IP2Long/Long2Ip](#user-content-ip2longlong2ip)\n    * [GetMxrr](#user-content-getmxrr)\n* [Math](#user-content-math)\n    * [Rand](#user-content-rand)\n* [Crypto](#user-content-crypt)\n    * [Md5](#user-content-md5)\n    * [Sha1](#user-content-sha1)\n    * [Sha2](#user-content-sha2)\n    * [HashFile](#user-content-hashfile)\n    * [HashHmac](#user-content-hashhmac)\n    * [IsValidMac](#user-content-isvalidmac)\n\n#### Installation\n\nVia go get command:\n\n```bash\ngo get github.com/arthurkushman/pgo\n```\n\nImagine that you need to write Go code every day and also have a convenient functions in memory from PHP experience\n\n### Core\n\n#### Serialize/Unserialize\n\nFor instance, to store Go code data in storage engines like rdbms, no-sql, key-value etc, you can use serialization\nfunctions to serialize Go code to string and unserialize it back from string to Go code:\n\n```go\nm := make(map[int]string)\nm[0] = \"abc\"\n\nstr, err := pgo.Serialize(m) // str -\u003e \"Dv+BBAEC/4IAAQQBDAAACf+CAAEAA2FiYw==\"\n\nunserMap := make(map[int]string)\nerr = pgo.Unserialize(str, \u0026unserMap) // unserMap -\u003e map[int]string{0: \"abc\"}\n```\n\n### Date\n\nYou can use date function with similar formatting for PHP e.g.:\n\n```go\ndateStr := pgo.Date(\"Y-m-d H:i:s\") // 2019-03-28 12:23:03\n\npgo.Date(\"j D, M\") // 27 Wed, Mar\n\npgo.Date(\"Q\") // 3 (of 1,2,3,4 quarters)\n```\n\n#### Milli/Micro\n\n```go\nnowMicro := pgo.UnixMicro() // get current unix microseconds\nnowMilli := pgo.UnixMilli() // get current unix milliseconds\n\n// get current millis + 3ms \nnowMillisPlusThree := pgo.Time(time.Now().Add(time.Millisecond * 3)).Milliseconds()\n// get current microseconds + 7μs \nnowMicroPlusSeven := pgo.Time(now.Add(time.Microsecond * 7)).Microseconds()\n```\n\n### Strings\n\n#### StrReplace\n\nreplace sub-strings with StrReplace:\n\n```go\nsubject := \"The quick brown fox jumped over the lazy dog\"\n\nstr, err := pgo.StrReplace([]string{\"fox\", \"dog\"}, []string{\"cat\", \"elephant\"}, subject)\n\n// and if case-insensitive replace needed - pgo.StrIReplace([]string{\"DOG\", \"QuiCK\"}, []string{\"fox\", \"slow\"}, subject) \n```\n\n#### HTTPBuildQuery\n\nBuilding a http query string:\n\n```go\nqueryStr := pgo.HTTPBuildQuery(map[string]interface{}{\n  \"foo\":      \"bar\",\n  \"bar\":      \"baz\",\n  \"s\":        []string{\"1\", \"foo\", \"2\", \"bar\", \"3\", \"baz\"},\n  \"num\":      123,\n  \"bigNum\":   int64(1238873737737737373),\n  \"amount\":   623.937,\n  \"isActive\": true,\n}) // amount=623.937\u0026bar=baz\u0026bigNum=1238873737737737373\u0026foo=bar\u0026isActive=true\u0026num=123\u0026s=1\u0026s=foo\u0026s=2\u0026s=bar\u0026s=3\u0026s=baz\n```\n\n#### StripTags\n\nStrip tags with exclusion rules:\n\n```go\nhtml := \"\u003cdiv\u003eLorem \u003cspan\u003eipsum dolor sit amet\u003c/span\u003e, consectetur adipiscing elit, sed do eiusmod \u003ca href=\\\"http://example.com\\\"\u003etempor incididunt\u003c/a\u003e ut labore \u003cstrong\u003eet dolore\u003c/strong\u003e magna aliqua.\u003c/div\u003e\"\n\nstr := html.StripTags(html, []string{\"a\", \"span\"}) // results in: \"Lorem \u003cspan\u003eipsum dolor sit amet\u003c/span\u003e, consectetur adipiscing elit, sed do eiusmod \u003ca href=\\\"http://example.com\\\"\u003etempor incididunt\u003c/a\u003e ut labore et dolore magna aliqua.\"\n```\n\nUPD: As had been stated here - https://github.com/golang/go/issues/22639\nThere is a very handy \"stripTags\" function in html/template, then guys from official team as fast as they got dislike on\ntheir negative comment, closed the thread. That is why libs like `pgo` is appearing and will be move forward/evolve,\nbypassing strict rules that sometimes looking nonsence.\n\n### Files\n\n#### FileGetContents\n\nRead files with offset/limit:\n\n```go\ncontent, err := pgo.FileGetContents(\"somefile.txt\", 0, 1024)\n```\n\n#### FilePutContents\n\nreflexively write to files with:\n\n```go\nn, err := pgo.FilePutContents(\"somefile.txt\", strToWrite, pgo.FileAppend)\n```\n\nRead from context (via http(s)):\n\n```go\ncontent, err := pgo.FileGetContents(\"http://google.com\", pgo.NewContext())\n```\n\n#### MoveUploadedFile\n\nUploading files from web-forms to your server:\n\n```go\nctx := pgo.NewContext()\nctx.Req = YourReq\nctx.UploadMaxFileSize = 10 \u003c\u003c 25\n\nuploaded := ctx.MoveUploadedFile(\"foo\", \"/srv/images/pic123.png\")\n```\n\n#### FileExists\n\nChecking for file existence\n\n```go\nif pgo.FileExists(\"file1.txt\") == true {\n// do something with existent file\n}\n```\n\n#### IsFile/IsDir/IsLink\n\nCheck if it is file/dir/symlink\n\n```go \nif pgo.IsFile(\"someFile.txt\") {\n\t// do something with file\n}\n\nif pgo.IsDir(\"someDir/\") {\n\t// do something with dir\n}\n\nif pgo.IsLink(\"someLink\") {\n\t// do somthing with symlink\n}\n```\n\n### Arrays\n\n#### InArray\n\nCheck if an array contains an element\n\n```go\npgo.InArray(3, []int{1, 2, 3}) // true\npgo.InArray(\"bar33\", []string{\"foo\", \"bar\", \"baz\"}) // false\npgo.InArray(3.14159, []float64{33.12, 12.333, 3.14159, 78.4429}) // true\n```\n\n#### ArrayChunk\n\nSplit an array by chunks (with auto-tailing)\n\n```go\npgo.ArrayChunk([]int{1, 2, 3, 4, 5, 6, 7, 8}, 2) // [][]int{[]int{1, 2}, []int{3, 4}, []int{5, 6}, []int{7, 8}}\n\npgo.ArrayChunk([]string{\"foo\", \"bar\", \"baz\", \"fizz\", \"buzz\"}, 3) // [][]string{[]string{\"foo\", \"bar\", \"baz\"}, []string{\"fizz\", \"buzz\"}}\n```\n\n#### ArrayCombine\n\nCreate an array by using one array for keys and another for its values\n\n```go\npgo.ArrayCombine([]int{11, 32, 13, 14, 51, 46, 17, 88}, []string{\"foo\", \"bar\", \"baz\", \"fizz\", \"buzz\", \"mazz\", \"freez\", \"lorum\"})\n/*\n   map[int]string{\n   \t\t11: \"foo\",\n   \t\t32: \"bar\",\n   \t\t13: \"baz\",\n   \t\t14: \"fizz\",\n   \t\t51: \"buzz\",\n   \t\t46: \"mazz\",\n   \t\t17: \"freez\",\n   \t\t88: \"lorum\",\n   \t}\n*/\npgo.ArrayCombine([]string{\"foo\", \"bar\", \"baz\", \"fizz\", \"buzz\"}, []float64{11.32, 32.42, 13.246, 14.41, 51.98})\n/*\nmap[string]float64{\n\t\t\t\"foo\":  11.32,\n\t\t\t\"bar\":  32.42,\n\t\t\t\"baz\":  13.246,\n\t\t\t\"fizz\": 14.41,\n\t\t\t\"buzz\": 51.98,\n\t\t}\n*/\n```\n\n#### ArrayCountValues\n\nCount all the values of an array/slice\n\n```go\npgo.ArrayCountValues([]string{\"foo\", \"bar\", \"foo\", \"baz\", \"bar\", \"bar\"}) // map[string]int{\"foo\": 2, \"bar\": 3, \"baz\": 1}\n\npgo.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}\n```\n\n#### ArrayMap\n\nApply the callback to the elements of the given arrays\n\n```go\npgo.ArrayMap([]string{\"foo\", \"bar\", \"baz\"}, func (v string) string {\nreturn strings.ToUpper(v)\n}) // []string{\"FOO\", \"BAR\", \"BAZ\"}\n\npgo.ArrayMap([]float64{1, 2, 3, 4, 5}, func (v float64) float64 {\nreturn math.Pow(v, 2)\n}) // []float64{1, 4, 9, 16, 25}\n```\n\n#### ArrayFilter\n\nfilters elements of an array using a callback function\n\n```go\npgo.ArrayFilter([]float64{1, 2, 3, 4, 5}, func (v float64) bool {\nreturn v \u003e 2.718\n}) // []float64{3, 4, 5}\n```\n\n#### ArrayDiff\n\nreturns the values in array1 that are not present in any of the other arrays\n\n```go\npgo.ArrayDiff([]string{\"foo\", \"bar\", \"fizz\", \"baz\"}, []string{\"foo\", \"bar\"}) // []string{\"fizz\", \"baz\"}\npgo.ArrayDiff([]int{3, 43, 8, 4, 9}, []int{3, 8, 9, 4}) // []int{43}\n```\n\n#### ArrayUdiff\n\ncomputes the difference of arrays by using a callback function for data comparison\n\n```go\npgo.ArrayUdiff(func (a interface{}, b interface{}) int {\n  if a.(string) \u003e b.(string) {\n    return 1\n  } else if a.(string) \u003c b.(string) {\n    return -1\n  }\n\n  return 0\n}, []string{\"foo\", \"bar\", \"fizz\", \"baz\"}, []string{\"foo\", \"bar\"}) // []string{\"fizz\", \"baz\"}\n\npgo.ArrayUdiff(func (a interface{}, b interface{}) int {\n  if a.(int) \u003e b.(int) {\n      return 1\n  } else if a.(int) \u003c b.(int) {\n      return -1\n  }\n  \n  return 0\n}, []int{3, 43, 8, 4, 9}, []int{3, 8, 9, 4}) // []int{43}\n```\n\n#### ArraySum\n\ncalculate the sum of values in an array\n\n```go\npgo.ArraySum([]int{12, 54, 32, 12, 33}) // int: 143\n```\n\n#### ArrayIntersect\n\ncomputes the intersection of arrays\n\n```go\npgo.ArrayIntersect([]int{12, 54, 32, 12, 33}, []int{3, 12, 54, 9}, []int{12, 33, 9}) // []int{12, 54, 33}\n\npgo.ArrayIntersect([]string{\"foo\", \"bar\", \"baz\", \"fizz\", \"bazz\", \"fizz\", \"fizz\"}, []string{\"bar\", \"fizz\"}, []string{\"foo\", \"bar\", \"hey\"}) // []string{\"foo\", \"bar\", \"fizz\"}\n```\n\n#### ArrayMin/ArrayMax\n\nfinds minimum/maximum value from []T\n\n```go\nres = pgo.ArrayMax([]int{3, 1, 2, 9}) // res == 9\nres = pgo.ArrayMax([]float64{-3.12, -1.678, -2.01, -9.007}) // res == -1.678\nres = pgo.ArrayMin([]int{3, 1, 2, 9}) // res == 1\nres = pgo.ArrayMin([]float64{3.2, 1.0837, 2.123, 9.87}) // res == 1.0837\n```\n\n#### ArrayUnique\n\nreturns unique values form []T\n\n```go\nres = pgo.ArrayUnique([]int{1, 2, 2, 3, 2, 4, 4}) // []int{1, 2, 3, 4}\n\nres = pgo.ArrayUnique([]string{\"foo\", \"bar\", \"foo\", \"bar\"}) // []string{\"bar\", \"foo\"}\n```\nNote: order is not guaranteed \n\n#### ArrayValues\n\nreturn all the values of map as a slice of values with corresponding type\n\n```go\nres = pgo.ArrayValues(map[string]int{\"a\": 1, \"b\": 2, \"c\": 3}) // []int{1, 2, 3}\n\nres = pgo.ArrayValues(map[int]float64{1: 123.33, 2: 22, 3: 123.33}) // []float64{22, 123.33, 123.33}\n```\n\n### ArrayReverse\n\nreverse slice passed as an argument\n\n```go\ntoReverse := []int{-3, 0, 4, 9, 13}\npgo.ArrayReverse(toReverse) \nfmt.Println(toReverse) // []int{13, 9, 4, 0, -3}\n```\n\n#### Range\n\ncreates an int slice of min to max range\n\n```go\npgo.Range(3, 9) // []int{3, 4, 5, 6, 7, 8, 9}\n\n// If a step value is given, it will be used as the increment between elements in the sequence.\npgo.Range(-3, 7, 5) // []int{-3, 2, 7}\n```\n\n#### EqualSlices\n\nCompares two slices and returns true if they are equal, false otherwise (any type of slices support)\n\n```go\nres, err := pgo.EqualSlices([]int{1, 2, 3}, []int{1, 2, 3}) // true\n\nres, err := pgo.EqualSlices([]string{\"foo\"}, []string{\"bar\"}) // false\n```\n\nSee more examples in *_test.go files.\n\n### Collections\n\n#### Priority Queue\n\n```go\n    // Some items and their priorities.\nitems := map[string]int{\n\"banana\": 3, \"apple\": 2, \"pear\": 4, \"peach\": 1, \"plum\": 6,\n}\n\n// Create a Priority queue, put the items in it, and\n// establish the Priority queue (heap) invariants.\npq := make(pgo.PriorityQueue, len(items))\ni := 0\nfor value, priority := range items {\npq[i] = \u0026pgo.Item{\nValue:    value,\nPriority: priority,\nIndex:    i,\n}\ni++\n}\npq.Init()\n\n// Insert a new item and then modify its Priority.\nitem := \u0026pgo.Item{\nValue:    \"orange\",\nPriority: 1,\n}\npq.Push(item)\npq.Update(item, item.Value, 5)\n\nitem := pq.Pop().(*pgo.Item) // 06:plum\nitem := pq.Pop().(*pgo.Item) // 05:orange\nitem := pq.Pop().(*pgo.Item) // 04:pear\nitem := pq.Pop().(*pgo.Item) // 03:banana\n// ... \n```\n\n### Network\n\n#### IP2Long/Long2Ip\n\n```go\nlong, _ := pgo.IP2long(\"176.59.34.117\") // 2956665461\n\nip := pgo.Long2ip(2956665461) // \"176.59.34.117\"\n```\n\n#### GetMxrr\n\n```go\nisMx, mxs, _ := pgo.GetMxrr(\"google.com\") // e.g.: true, n\n```\n\n### Math\n\n#### Rand\n\n```go\nrand := pgo.Rand(1, 100)\n```\n\n### Crypto\n\n#### Md5\n\n```go\npgo.Md5(\"abc123\") // e99a18c428cb38d5f260853678922e03\n```\n\n#### Sha1\n\n```go\npgo.Sha1(\"abc123\") // 6367c48dd193d56ea7b0baad25b19455e529f5ee\n```\n\n#### Sha2\n\n```go\npgo.Sha2(\"abc123\") // 6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090\n```\n\n#### HashFile\n\n```go\nhex, err := pgo.HashFile(\"sha1\", \"example.txt\") // 6367c48dd193d56ea7b0baad25b19455e529f5ee\n```\n\n#### HashHmac\n\n```go\nhmac := HashHmac(\"foo bar baz\", \"secret\", sha256.New) // 9efc4f86917b454deae37c869521f88dee79305303fa2283df0b480e3cc8104c\n```\n\n#### IsValidMac\n\n```go\nIsValidMac(\"foo bar baz\", hmac, \"secret\", sha256.New) // true/false\n```\n\nSupporters gratitude:\n\n\u003cimg src=\"https://github.com/SoliDry/laravel-api/blob/master/tests/images/jetbrains-logo.png\" alt=\"JetBrains logo\" width=\"200\" height=\"166\" /\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farthurkushman%2Fpgo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farthurkushman%2Fpgo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farthurkushman%2Fpgo/lists"}