Gin 使用方法

  1. 基础用法:
package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()

	r.GET("/", func(c *gin.Context) {
		c.String(200, "Index")
	})

	r.GET("/user/:name", func(c *gin.Context) {
		name := c.Param("name")
		c.String(http.StatusOK, "Hello %s", name)
	})

	r.POST("/form", func(c *gin.Context) {
		username := c.PostForm("username")
		password := c.DefaultPostForm("password", "000000")

		c.JSON(http.StatusOK, gin.H{
			"username": username,
			"password": password,
		})
	})

	r.POST("/upload", func(c *gin.Context) {
		file, _ := c.FormFile("file")
		// c.SaveUploadedFile(file, dst)
		c.String(http.StatusOK, "%s uploaded!", file.Filename)
	})

	r.Run("0.0.0.0:8800")
}

2. 常用方法

// c.Abort() 
// c.AbortWithError(code int, err error) *Error 
// c.AbortWithStatus(code int) 
// c.AbortWithStatusJSON(code int, jsonObj interface}) 
// c.AsciiJSON(code int, obj interface}) 
// c.Bind(obj interface}) error 
// c.BindHeader(obj interface}) error 
// c.BindJSON(obj interface}) error 
// c.BindQuery(obj interface}) error 
// c.BindUri(obj interface}) error 
// c.BindXML(obj interface}) error 
// c.BindYAML(obj interface}) error 
// c.ClientIP() string 
// c.ContentType() string 
// c.Cookie(name string) (string, error) 
// c.Data(code int, contentType string, data []byte) 
// c.DataFromReader(code int, contentLength int64, contentType string, reader io.Reader, extraHeaders map[string]string) 
// c.Deadline() (deadline time.Time, ok bool) 
// c.DefaultPostForm(key, defaultValue string) string 
// c.DefaultQuery(key, defaultValue string) string 
// c.Done() <-chan struct} 
// c.Err() error 
// c.Error(err error) *Error 
// c.File(filepath string) 
// c.FileAttachment(filepath, filename string) 
// c.FileFromFS(filepath string, fs http.FileSystem) 
// c.FormFile(name string) (*multipart.FileHeader, error) 
// c.FullPath() string 
// c.func bodyAllowedForStatus(status int) bool 
// c.func validateHeader(header string) (clientIP string, valid bool) 
// c.Get(key string) (value interface}, exists bool) 
// c.get(m map[string][]string, key string) (map[string]string, bool) 
// c.GetBool(key string) (b bool) 
// c.GetDuration(key string) (d time.Duration) 
// c.GetFloat64(key string) (f64 float64) 
// c.GetHeader(key string) string 
// c.GetInt(key string) (i int) 
// c.GetInt64(key string) (i64 int64) 
// c.GetPostForm(key string) (string, bool) 
// c.GetPostFormArray(key string) ([]string, bool) 
// c.GetPostFormMap(key string) (map[string]string, bool) 
// c.GetQuery(key string) (string, bool) 
// c.GetQueryArray(key string) ([]string, bool) 
// c.GetQueryMap(key string) (map[string]string, bool) 
// c.GetRawData() ([]byte, error) 
// c.GetString(key string) (s string) 
// c.GetStringMap(key string) (sm map[string]interface}) 
// c.GetStringMapString(key string) (sms map[string]string) 
// c.GetStringMapStringSlice(key string) (smss map[string][]string) 
// c.GetStringSlice(key string) (ss []string) 
// c.GetTime(key string) (t time.Time) 
// c.GetUint(key string) (ui uint) 
// c.GetUint64(key string) (ui64 uint64) 
// c.Handler() HandlerFunc 
// c.HandlerName() string 
// c.HandlerNames() []string 
// c.Header(key, value string) 
// c.HTML(code int, name string, obj interface}) 
// c.IndentedJSON(code int, obj interface}) 
// c.initFormCache() 
// c.initQueryCache() 
// c.IsAborted() bool 
// c.IsWebsocket() bool 
// c.JSON(code int, obj interface}) 
// c.JSONP(code int, obj interface}) 
// c.MultipartForm() (*multipart.Form, error) 
// c.MustBindWith(obj interface}, b binding.Binding) error 
// c.MustGet(key string) interface} 
// c.Negotiate(code int, config Negotiate) 
// c.NegotiateFormat(offered ...string) string 
// c.Next() 
// c.Param(key string) string 
// c.PostForm(key string) string 
// c.PostFormArray(key string) []string 
// c.PostFormMap(key string) map[string]string 
// c.ProtoBuf(code int, obj interface}) 
// c.PureJSON(code int, obj interface}) 
// c.Query(key string) string 
// c.QueryArray(key string) []string 
// c.QueryMap(key string) map[string]string 
// c.Redirect(code int, location string) 
// c.RemoteIP() (net.IP, bool) 
// c.Render(code int, r render.Render) 
// c.requestHeader(key string) string 
// c.SaveUploadedFile(file *multipart.FileHeader, dst string) error 
// c.SecureJSON(code int, obj interface}) 
// c.Set(key string, value interface}) 
// c.SetAccepted(formats ...string) 
// c.SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool) 
// c.SetSameSite(samesite http.SameSite) 
// c.ShouldBind(obj interface}) error 
// c.ShouldBindBodyWith(obj interface}, bb binding.BindingBody) (err error) 
// c.ShouldBindHeader(obj interface}) error 
// c.ShouldBindJSON(obj interface}) error 
// c.ShouldBindQuery(obj interface}) error 
// c.ShouldBindUri(obj interface}) error 
// c.ShouldBindWith(obj interface}, b binding.Binding) error 
// c.ShouldBindXML(obj interface}) error 
// c.ShouldBindYAML(obj interface}) error 
// c.SSEvent(name string, message interface}) 
// c.Status(code int) 
// c.Stream(step func(w io.Writer) bool) bool 
// c.String(code int, format string, values ...interface}) 
// c.Value(key interface}) interface} 
// c.XML(code int, obj interface}) 
// c.YAML(code int, obj interface}) 
发布于
归类为Golang

Golang网络函数

抓取网页内容

func getHtmlContent(u string, r string) []string {
	resp, err := http.Get(u)
	if err != nil {
		log.Println(err.Error())
		return nil
	}
	defer resp.Body.Close()

	if resp.StatusCode == http.StatusOK {
		c, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			log.Println(err.Error())
			return nil
		}

		return regexp.MustCompile(`href=".*"`).FindAllString(string(c), -1)
	} else {
		log.Println("Error HTML Code: ", resp.StatusCode)
		return nil
	}
}
发布于
归类为Golang

树莓派编译安装PHP7.4

首先安装依赖

apt install -y libxml2 libxml2-dev libjpeg-dev libcurl4-openssl-dev libreadline-dev libzip-dev libfreetype6-dev libssl-dev libsqlite3-dev libonig-dev

下载源码并编译安装

wget https://www.php.net/distributions/php-7.4.15.tar.gz
tar zxf php-7.4.15.tar.gz
cd php-7.4.15

./configure \
--prefix=/usr/local/php \
--with-curl --with-freetype --with-gettext --with-iconv-dir --with-jpeg --with-libdir=lib64 --with-openssl --with-pear --with-readline --with-xmlrpc --with-zip --with-zlib \
--with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd \
--enable-bcmath --enable-calendar --enable-exif --enable-fpm --enable-ftp --enable-gd --enable-intl --enable-mbstring --enable-mysqlnd --enable-pcntl \
--enable-soap --enable-sockets
make -j8 && make install

配置文件

cp php.ini-production /usr/local/php/lib/php.ini
sed -i 's/post_max_size = 8M/post_max_size = 50M/g' /usr/local/php/lib/php.ini
sed -i 's/upload_max_filesize = 2M/upload_max_filesize = 50M/g' /usr/local/php/lib/php.ini
sed -i 's/;date.timezone =/date.timezone = PRC/g' /usr/local/php/lib/php.ini
sed -i 's/expose_php = On/expose_php = Off/g' /usr/local/php/lib/php.ini

树莓派自动解析IPV6地址

自动解析树莓派的 IPV6 地址到某个域名

<?php

// 调试模式
define('DebugModel', false);

// 域名
define('Domain', 'device.raspberrypi.org');

// Clouflare API 地址
define('ClouflareApiBase', 'https://api.cloudflare.com/client/v4');

// Clouflare API 密钥
define('ClouflareAuthKey', 'ClouflareAuthKey');

/**
 *  获取本机 IPV6 地址
 */
function getIPV6()
{
    if (!file_exists('/proc/net/if_inet6')) {
        throw new Exception("Get IPV6 Failed!");
    }
    $_ipv6 = explode(" ", file_get_contents('/proc/net/if_inet6'))[0];
    debug('Getting IPV6');
    return implode(':', str_split($_ipv6, 4));
}

/**
 *  获取顶级域名
 */
function getMainDomain($domain)
{
    $_domain = explode('.', $domain);
    $domain = [];
    $domain[] = array_pop($_domain);
    $domain[] = array_pop($_domain);
    debug('Getting Main Domain');
    return $domain[1] . '.' . $domain[0];
}

/**
 *  获取域名 Zone ID
 */
function getZoneID($domain)
{
    $mainDomain = getMainDomain($domain);
    $url = sprintf('%s/zones', ClouflareApiBase);
    debug('Send ZoneID Request');
    $dns = json_decode(httpRequest('GET', $url));
    debug('Get ZoneID Response');
    if (isset($dns->result)) {
        foreach ($dns->result as $v) {
            if ($v->name === $mainDomain) {
                return $v->id;
            }
        }
    } else {
        throw new Exception("Get ZoneID Failed!");
    }
}

/**
 *  获取域名 Record
 */
function getRecord($zoneID, $domain, $type = 'A')
{
    $url = sprintf('%s/zones/%s/dns_records', ClouflareApiBase, $zoneID);
    debug('Send RecordID Request');
    $dns = json_decode(httpRequest('GET', $url));
    debug('Get RecordID Response');
    if (isset($dns->result)) {
        foreach ($dns->result as $v) {
            if ($v->name === $domain && $v->type === $type) {
                return $v;
            }
        }
    }
    return false;
}

/**
 *  新增域名解析
 */
function setRecord($zoneID, $domain, $ipv6)
{
    $data = array(
        'name' => $domain,
        'type' => 'AAAA',
        'content' => $ipv6,
        'ttl' => 120
    );
    $url = sprintf('%s/zones/%s/dns_records', ClouflareApiBase, $zoneID);
    $response = json_decode(httpRequest('POST', $url, json_encode($data)));
    if (isset($response->result->id)) {
        return true;
    } else {
        return false;
    }
}

/**
 *  更新域名解析
 */
function updateRecord($zoneID, $recordID, $domain, $ipv6)
{
    $data = array(
        'name' => $domain,
        'type' => 'AAAA',
        'content' => $ipv6,
        'ttl' => 120
    );
    $url = sprintf('%s/zones/%s/dns_records/%s', ClouflareApiBase, $zoneID, $recordID);
    $response = json_decode(httpRequest('PUT', $url, json_encode($data)));
    if (isset($response->result->id)) {
        return true;
    } else {
        return false;
    }
}

/**
 *  发起 HTTP 请求
 */
function httpRequest($method = 'GET', $url, $post = '')
{
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_ENCODING, 'gzip');
    curl_setopt($curl, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . ClouflareAuthKey, 'Content-Type: application/json']);

    if ($method !== 'GET') {
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
    }

    $data = curl_exec($curl);
    $error = curl_error($curl);
    curl_close($curl);

    if ($error) {
        throw new Exception($error);
    } else {
        return $data;
    }
}

function debug($log)
{
    if (DebugModel) {
        $file = '/tmp/dns.log';
        $log = date('Y-m-d H:i:s') . "\t" . $log . "\n";
        echo $log;
        file_put_contents($file, $log, FILE_APPEND);
    }
}

function main($domain)
{
    $ipv6 = getIPV6();
    $zoneID = getZoneID($domain);
    $record = getRecord($zoneID, $domain, 'AAAA');
    if (isset($record->id)) {
        if ($record->content !== $ipv6) {
            debug('Update IPV6 Record');
            $update = updateRecord($zoneID, $record->id, $domain, $ipv6);
        } else {
            return debug('No Change IPV6 Record');
        }
    } else {
        debug('New IPV6 Record');
        $update = setRecord($zoneID, $domain, $ipv6);
    }
    if ($update) {
        debug('DNS Record Update Success!');
    } else {
        debug('DNS Record Update Failed!');
    }
}

main(Domain);

Hyperf 环境配置和安装

安装 PHP 环境

# PHP 7.3.19
# Swoole 4.5.2
# Composer 1.10.10

配置阿里云镜像源

composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

安装 Hyperf

composer create-project hyperf/hyperf-skeleton

Docker 方式安装

docker run -v D:\wamp\www\html\hyperf:/hyperf-skeleton -p 9501:9501 -it --entrypoint /bin/sh hyperf/hyperf:latest
发布于
归类为php

Guzzle 使用文档

安装

composer require guzzlehttp/guzzle:7.0.1

发起 Get 请求

use GuzzleHttp\Client as guzzleClient;

$guzzleClient = new guzzleClient([
    'timeout' => 2.0
]);

// 同步请求方式
$response = $guzzleClient->get('http://api.org/get', ['headers' => ['User-Agent' => 'Guzzle'], 'http_errors' => false]);
$code = $response->getStatusCode();
$body = $response->getBody();
$content = $body->getContents();
// 异步请求方式
$promise = $guzzleClient->getAsync('http://api.org/get');
$promise->then(
    function (ResponseInterface $res) {
        echo $res->getStatusCode() . "\n";
    },
    function (RequestException $e) {
        echo $e->getMessage() . "\n";
        echo $e->getRequest()->getMethod();
    }
);

发起 Post 请求

use GuzzleHttp\Client as guzzleClient;

$guzzleClient = new guzzleClient([
    'timeout' => 2.0
]);

// 原始类型
$response = $guzzleClient->post('http://api.org/post', [
    'body' => 'raw data'
]);

// json 类型 application/json
$response = $guzzleClient->post('http://api.org/post', [
    'json' => ['name' => 'admin']
]);

// 表单类型 application/x-www-form-urlencoded
$response = $guzzleClient->post('http://api.org/post', [
    'form_params' => [
        'username' => 'abc',
        'password' => '123'
    ]
]);

// 上传文件 multipart/form-data
$response = $guzzleClient->post('http://api.org/post', [
    'multipart' => [
        [
            'name'     => 'user',
            'contents' => 'admin'
        ],
        [
            'name'     => 'file',
            'contents' => fopen('/path/to/file', 'r')
        ],
    ]
]);
发布于
归类为php

EasySwoole环境和框架安装

安装 PHP 环境

# PHP 7.3.19
# Swoole 4.5.2
# Composer 1.10.10

配置阿里云镜像源

composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

安装 EasySwoole

composer require easyswoole/easyswoole=3.3.7
php vendor/easyswoole/easyswoole/bin/easyswoole install
composer dump-autoload

安装 RPC 组件

composer require easyswoole/rpc=4.0.10

启动 EasySwoole

php easyswoole start
发布于
归类为php

Git 常用配置参数

Windows 开发环境:

# 忽略路径中的转义字符

git config --global core.protectNTFS false

# 禁用换行符转换

git config --global core.autocrlf false

发布于
归类为Linux

CentOS7自动添加防火墙白名单

自动添加某域名对应的IP地址到防火墙里,允许此IP访问SSH服务

package main

import (
	"fmt"
	"net"
	"os/exec"
	"strings"
)

func main() {
	ip, err := net.ResolveIPAddr("ip4", "test.com")
	if err != nil {
		return
	}
	command, err := exec.Command("bash", "-c", "firewall-cmd --list-all").Output()
	if err != nil {
		return
	}
	if strings.Contains(string(command), ip.String()) {
		return
	}
	comm := `firewall-cmd --add-rich-rule='rule family="ipv4" source address="` + ip.String() + `" port port="22" protocol="tcp" accept'`
	_, err = exec.Command("bash", "-c", comm).Output()
	if err != nil {
		fmt.Println(err.Error())
		return
	}
}
发布于
归类为Linux