PHP 优秀资源汇集[2020.11.08更新]

以下是我整理好的 PHP 资源,各位看官拿去用,不用再自己找了。

GitHub 上稳定更新,觉得不错请点个 Star ❤️

如转载分享,请保留出处,谢谢 😆

原文地址: https://shockerli.net/post/php-awesome

GitHub: https://github.com/shockerli/php-awesome

Go 语言规范 - 编码风格(2020)

当前版本: v1.0.20201106

GitHub: shockerli/go-code-guide

命名规则

  • 站在调用者的角度,包不是给你自己用的
  • 简洁、且见名知义
  • 采用通用、大众熟知的缩写命名。比如buf而不是bufio
  • 如果缩写的名字会产生歧义,则放弃或换个

文件名

整个应用或包的主入口文件应当是 main.go,或与应用名称简写相同。

比如:spiker 包的主入口文件是 spiker.go,应用的主入口文件是 main.go

包名

  • 包名与目录名一致

    如果一个目录下同时出现多个 package,则编译失败:

    1
    
    found packages pkg (a.go) and pb (b.go) in XXX
    
  • 大多数使用命名导入的情况下,不需要重命名

    少让调用者去起别名,除非名字太烂

  • 全部小写,没有下划线、大写。错误示例MyPackagemy_packagemyPackage

  • 不用复数。例如net/url,而不是net/urls

  • 不用信息量不足的名字。错误示例commonlibutil

Go 语言优秀资源整理,为项目落地加速🏃[2020.11.02更新]

Go 语言优秀资源整理,为项目落地加速🏃

GitHub 上稳定更新,觉得不错请点个 Star ❤️

如转载分享,请保留出处,谢谢 😆

原文地址: https://shockerli.net/post/go-awesome

GitHub: https://github.com/shockerli/go-awesome


官网: https://golang.org

国内官网镜像(访问快~): https://golang.google.cn

GitHub: https://github.com/golang/go

开发者平台: https://go.dev

Wiki: https://github.com/golang/go/wiki

官方博客: https://blog.golang.org

指导原则

  • 简单性

    复杂性把可读的程序变得不可读,复杂性终结了很多软件项目。

  • 可读性

    代码是给人看的,代码阅读时长远超编写。程序必须可维护,那可读是第一步。

  • 生产率

    拥有众多的工具集和基础库,可以很简单方便的完成绝大多数工作。 编译速度足够快,拥有动态语言的高效,但却不会面临动态语言不可靠的问题。 自带编程规范,使得团队代码一致,也帮助开发者发现和避免潜在的错误。

Awesome

Gin 框架绑定 JSON 参数使用 jsoniter

Gin 框架中,处理 JSON 格式的参数绑定时,默认采用的标准包 encoding/json,然而标准包不能满足我们的一些要求,比如兼容字符串整型、PHP空数组、时间格式等。

最简单的方式

开发 API 时,需要用到 ShouldBindJSON 绑定传入的参数到结构体:

1
2
3
4
5
6
// github.com/gin-gonic/gin@v1.6.3/context.go:643

// ShouldBindJSON is a shortcut for c.ShouldBindWith(obj, binding.JSON).
func (c *Context) ShouldBindJSON(obj interface{}) error {
	return c.ShouldBindWith(obj, binding.JSON)
}

Gin 默认采用 encoding/json 包:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// github.com/gin-gonic/gin@v1.6.3/internal/json/json.go
// +build !jsoniter

package json

import "encoding/json"

var (
	// Marshal is exported by gin/json package.
	Marshal = json.Marshal
	// Unmarshal is exported by gin/json package.
	Unmarshal = json.Unmarshal
	// MarshalIndent is exported by gin/json package.
	MarshalIndent = json.MarshalIndent
	// NewDecoder is exported by gin/json package.
	NewDecoder = json.NewDecoder
	// NewEncoder is exported by gin/json package.
	NewEncoder = json.NewEncoder
)

Go 字符串拼接的 7 种姿势

姿势一览

String Concat

1
str += "test-string"

String Sprintf

1
str = fmt.Sprintf("%s%s", str, "test-string")

String Join

1
str = strings.Join([]string{str, "test-string"}, "")

Go 挖坑指南: “cannot take the address of XXX” and “cannot call pointer method on XXX”

先看代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package main

type B struct {
    Id int
}

func New() B {
    return B{}
}

func New2() *B {
    return &B{}
}

func (b *B) Hello() {
    return
}

func (b B) World() {
    return
}

func main() {
    // 方法的接收器为 *T 类型
    New().Hello() // 编译不通过

    b1 := New()
    b1.Hello() // 编译通过

    b2 := B{}
    b2.Hello() // 编译通过

    (B{}).Hello() // 编译不通过
    B{}.Hello()   // 编译不通过

    New2().Hello() // 编译通过

    b3 := New2()
    b3.Hello() // 编译通过

    b4 := &B{} // 编译通过
    b4.Hello() // 编译通过

    (&B{}).Hello() // 编译通过

    // 方法的接收器为 T 类型
    New().World() // 编译通过

    b5 := New()
    b5.World() // 编译通过

    b6 := B{}
    b6.World() // 编译通过

    (B{}).World() // 编译通过
    B{}.World()   // 编译通过

    New2().World() // 编译通过

    b7 := New2()
    b7.World() // 编译通过

    b8 := &B{} // 编译通过
    b8.World() // 编译通过

    (&B{}).World() // 编译通过
}

图书推荐 [2019.10.23更新]

我所阅读或了解的优秀书籍,推荐给大家,不限于技术,各种类型都有,其实更多的是历史、传记等。

历史

书名 说明 推荐指数
用年表读懂中国史 中国历史入门书籍 ★★★★★
流血的仕途(全2册) 站在大秦丞相李斯的角度讲述其一生仕途的历史小说 ★★★★★
大秦帝国(全6部) 讲述自商鞅变法起的秦国历史小说 ★★★★★
如果这是宋史(全10册) 高天流云 ★★★★
明朝那些事儿(全7册) 当年明月 ★★★★
中国的匈奴 杨献平 ★★★
贾志刚说春秋(全7册) 贾志刚 ★★★★
血腥的盛唐(全7册) 王觉仁 ★★★★
中国近代通史(全10册) 1840-1949,可能是最权威、最全面的近代史丛书 ★★★★
贞观政要 记载了唐太宗在位的二十三年中一些政治、经济上的重大措施 ★★★★
罗马人的故事(全15册) 盐野七生 ★★★★

一键解决 go get golang.org/x 包失败

问题描述

当我们使用 go getgo installgo mod 等命令时,会自动下载相应的包或依赖包。但由于众所周知的原因,类似于 golang.org/x/... 的包会出现下载失败的情况。如下所示:

1
2
3
$ go get -u golang.org/x/sys

go get golang.org/x/sys: unrecognized import path "golang.org/x/sys" (https fetch: Get https://golang.org/x/sys?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)

PHP 实现字符串表达式计算

什么是字符串表达式?即,将我们常见的表达式文本写到了字符串中,如:"$age >= 20"$age 的值是动态的整型变量。

什么是字符串表达式计算?即,我们需要一段程序来执行动态的表达式,如给定一个含表达式的字符串变量并计算其结果,而表达式字符串是动态的,比如为客户A执行的表达式是 $orderCount >= 10,而为客户B执行的表达式是 $orderTotal >= 1000

场景在哪儿?同一份程序具有完全通用性,但差异就其中一个表达式而已,那么我们需要将其抽象出来,让表达式变成动态的、可配置的、或可生成的。

方案一:eval 函数

eval 函数可能是我们第一个想到的方案,也是最简单直接的方案。我们来试验下:

1
2
3
4
5
$a = 10;
var_dump(eval('return $a > 5;'));

// 输出:
// bool(true)

嗯~完全能满足我们的需求,因为 eval 函数执行的 PHP 表达式,只要字符串内表达式符合 PHP 语法就行。

但需注意的是,eval 函数可执行任意 PHP 代码,也就意味着权限大、风险高、不安全。如果你的字符串表达式来自于外部输入,那务必注意了请自行做好安全检查和过滤,并考虑风险。当然,执行的是外部输入表达式,非常不建议使用此函数。

解决 Homebrew 安装软件下载失败

当我们使用 Homebrew 安装软件时,由于一些特殊原因会出现软件包下载失败的情况。这种还很常见,我们没法改变环境,但却可以取巧的解决,那就是利用 Homebrew 缓存的特性,手动预先下载软件。

方法一: 手动下载软件包到缓存目录

以安装 Dart 为例:

1
2
3
4
5
6
7
8
$ brew install dart
==> Installing dart from dart-lang/dart
==> Downloading https://storage.googleapis.com/dart-archive/channels/stable/release/2.4.1/sdk/dartsdk-macos-x64-release.zip

curl: (56) LibreSSL SSL_read: SSL_ERROR_SYSCALL, errno 54
Error: An exception occurred within a child process:
  DownloadError: Failed to download resource "dart"
Download failed: https://storage.googleapis.com/dart-archive/channels/stable/release/2.4.1/sdk/dartsdk-macos-x64-release.zip