踏浪


  • 首页

  • 分类

  • 标签

  • 归档

  • 搜索

hexo多终端发布博客

发表于 2019-10-12 | 分类于 Hexo | | 阅读次数:

网站的部署其实就是生成静态文件,hexo下所有生成的静态文件会放在public/文件夹中,所谓部署deploy其实就是
将public/文件夹中内容上传到git仓库

换了电脑怎么办?

在现有的guthub.io的repository下创建一个分支来管理

  1. 克隆仓库到本地
1
git clone git@github.com:XXX.github.io.git
  1. 删除文件夹里除了.git的其他所有文件
  2. 创建一个叫hexo(或者blog,名字随意)的分支,并切换到这个分支
1
git checkout -b hexo
  1. 把你的blog文件夹内的所有文件全部复制到XXX.github.io/下
  2. 添加文件,推送到远程仓库
1
2
3
4
5
6
7
8
# 添加所有文件到暂存区
git add --all

#提交
git commit -m ""

#推送hexo分支的文件到github仓库
git push --set-upstream origin hexo

最后的效果就是仓库中的master放到是生成博客页面的文件(也就是blog/public/下的的文件),分支hexo中存放的就是我们备份的必要的blog中的文件。

发布博客后,执行指令,将备份的文件推送到hexo分支

1
2
3
4

git add . #添加所有文件到暂存区
git commit -m "提交一篇博客" #提交
git push origin hexo 推送hexo分支到github

今后如果换电脑的话,配置好基本的环境,然后克隆hexo分支到本地,npm install 安装依赖

1
2

git clone -b hexo git@github.com:XXX.github.io.git

综上所述

新建博客hexo new post “你好,hexo” ,然后去blog\source_posts 编辑文章。以后每次写完博客,通过hexo g,hexo d发布博客,然后通过git三部曲git add . ; git commit -m “注释” ; git push origin hexo更新备份github的hexo分支即可

CURL常用命令

发表于 2019-08-07 | 分类于 Linux | | 阅读次数:

下载单个文件

1
2
3
4
5
# 将文件下载到本地并命名为mygettext.html
curl -o mygettext.html http://www.gnu.org/software/gettext/manual/gettext.html

# 将文件保存到本地并命名为gettext.html
curl -O http://www.gnu.org/software/gettext/manual/gettext.html

断点续传

通过使用-C选项可对大文件使用断点续传功能

1
2
3
4
5
6
7
# 当文件在下载完成之前结束该进程
$ curl -O http://www.gnu.org/software/gettext/manual/gettext.html
############## 20.1%

# 通过添加-C选项继续对该文件进行下载,已经下载过的文件不会被重新下载
curl -C - -O http://www.gnu.org/software/gettext/manual/gettext.html
############### 21.1%

下载指定时间内修改过的文件

当下载一个文件时,可对该文件的最后修改日期进行判断,如果该文件在指定日期内修改过,就进行下载,否则不下载。
该功能可通过使用-z选项来实现:

1
2
# 若yy.html文件在2011/12/21之后有过更新才会进行下载
curl -z 21-Dec-11 http://www.example.com/yy.html

CURL授权

在访问需要授权的页面时,可通过-u选项提供用户名和密码进行授权

1
2
3
curl -u username:password URL 
# 通常的做法是在命令行只输入用户名,之后会提示输入密码,这样可以保证在查看历史记录时不会将密码泄露
curl -u username URL

从FTP服务器下载文件

CURL同样支持FTP下载,若在url中指定的是某个文件路径而非具体的某个要下载的文件名,CURL则会列出该目录下的所有文件名而并非下载该目录下的所有文件

1
2
3
4
5
# 列出public_html下的所有文件夹和文件
curl -u ftpuser:ftppass -O ftp://ftp_server/public_html/

# 下载xss.php文件
curl -u ftpuser:ftppass -O ftp://ftp_server/public_html/xss.php

保存与使用网站cookie信息

1
2
3
4
5
# 将网站的cookies信息保存到sugarcookies文件中
curl -D sugarcookies http://localhost/sugarcrm/index.php

# 使用上次保存的cookie信息
curl -b sugarcookies http://localhost/sugarcrm/index.php

传递请求数据

默认curl使用GET方式请求数据,这种方式下直接通过URL传递数据
可以通过 –data/-d 方式指定使用POST方式传递数据

1
2
3
4
5
6
7
8
# GET
curl -u username https://api.github.com/user?access_token=XXXXXXXXXX

# POST
curl -u username --data "param1=value1&param2=value" https://api.github.com

# 也可以指定一个文件,将该文件中的内容当作数据传递给服务器端
curl --data @filename https://github.api.com/authorizations

注:默认情况下,通过POST方式传递过去的数据中若有特殊字符,首先需要将特殊字符转义在传递给服务器端,如value值中包含有空格,则需要先将空格转换成%20,如:

1
curl -d "value%201" http://hostname.com

在新版本的CURL中,提供了新的选项 –data-urlencode,通过该选项提供的参数会自动转义特殊字符。

1
curl --data-urlencode "value 1" http://hostname.com

除了使用GET和POST协议外,还可以通过 -X 选项指定其它协议,如:

1
curl -I -X DELETE https://api.github.cim

上传文件

1
curl --form "fileupload=@filename.txt" http://hostname/resource

Linux split文件分割命令

发表于 2019-07-24 | 分类于 Linux | | 阅读次数:

Linux split命令用于将一个文件分割成数个。

该指令将大文件分割成较小的文件,在默认情况下将按照每1000行切割成一个小文件。

1
split [--help][--version][-<行数>][-b <字节>][-C <字节>][-l <行数>][要切割的文件][输出文件名]

参数说明:

  • -<行数> : 指定每多少行切成一个小文件
  • -b<字节> : 指定每多少字节切成一个小文件
  • –help : 在线帮助
  • –version : 显示版本信息
  • -C<字节> : 与参数”-b”相似,但是在切 割时将尽量维持每行的完整性
  • [输出文件名] : 设置切割后文件的前置文件名, split会自动在前置文件名后再加上编号

指定分割文件行数

例如将一个1.txt文件分成前缀为 o_ 的多个小文件,每个文件5000行(-l 5000)后缀为系数形式,系数不是字母而是数字(-d),后缀系数为四位数(-a 4)

1
split -l 5000 1.txt -d -a 4 o_

生成文件名如下:

‘o_0000’,’o_0001’,’o_0002’,’o_0003’

指定分割后文件大小

split -b 10m 1.log log

awk文本处理示例

发表于 2019-05-09 | 分类于 awk | | 阅读次数:

awk命令提供了用于文本处理的脚本语言。使用awk脚本语言,您可以进行以下操作

  • 定义变量
  • 使用字符串和算术运算符
  • 使用控制流和循环
  • 生成格式化报告

实际上,您可以处理包含数百万行的日志文件,以输出可读报告。

awk 选项

awk 命令使用方法如下

1
$ awk options program file

awk 能设置以下参数:

-F fs 指定文件分隔符.

-f file 指定包含awk脚本的文件.

-v var=value 声明一个变量.

读取awk脚本

定义一个awk脚本, 使用单引号包围的花括号标记

1
$ awk '{print "Welcome to awk command tutorial "}'

使用变量

使用awk, 你能处理文本文件. awk 为每一个数据字段赋值了变量:

  • $0 表示整行
  • $1 表示第一个字段
  • $2 表示第二个字段
  • $n 表示第N个字段.

像空格或制表符这样的空白字符是awk中字段之间的默认分隔符

$ awk '{print $1}' myfile   

D:\>cat myfile
This is a test.
This is the second test.
This is the thrid test.
This is the fourth test.

D:\>awk '{print $1}' myfile
This
This
This
This

上面的例子打印每行的第一个单词

有时某些文件中的分隔符不是空格,也不是制表符,而是其他内容。您可以使用-F选项指定它

1
$ awk -F: '{print $1}' /etc/passwd

此命令打印passwd文件中的第一个字段。我们使用冒号作为分隔符,因为passwd文件使用它

使用多个命令

要运行多个命令,请使用这样的分号分隔它们

1
$ echo "Hello Tom" | awk '{$2="Adam"; print $0}'

第一个命令使$2字段等于Adam。第二个命令打印整行

从文件中读取脚本

您可以在文件中键入awk脚本,并使用-f选项指定该文件。

这里我们从/etc/passwd打印用户名和他的路径,当然分隔符是用大写字母-F指定的

awk脚本testfile如下

{

text = $1 " home at " $6

print text  

}

$ awk -F: -f testfile /etc/passwd

awk预处理

如果您需要为结果创建标题。您可以使用BEGIN关键字来实现此目的。它在处理数据之前运行

$ awk 'BEGIN {print "Report Title"}'

$ awk 'BEGIN {print "The File Contents:"} {print $0}' myfile

awk后处理

在处理数据后运行脚本,使用END关键字:

$ awk 'BEGIN {print "The File Contents:"} {print $0} END {print "File footer"}' myfile

这很有用,您可以使用它来添加页脚

让我们将它们组合在一个脚本文件中:

BEGIN {
        print "Users and thier corresponding home"

        print " UserName \t HomePath"

        print "___________ \t __________"

        FS=":"
    }
    {
        print $1 "  \t  " $6
    }

    END {
    print "The end"

}

首先,使用BEGIN关键字创建顶部。然后我们定义FS并在末尾打印页脚

$ awk -f myscript  /etc/passwd

内置变量

变量$1,$2 ,$3用于提取数据字段,我们还处理字段分隔符FS。

但这些不是唯一的变量,还有更多的内置变量。

以下列表显示了一些内置变量:

  • FIELDWIDTHS 指定字段宽度.
  • RS 指定记录分隔符.
  • FS 指定字段分隔符.
  • OFS 指定输出分隔符.
  • ORS 指定输出分隔符.

OFS 默认值是空格, 你能指定它

$ awk 'BEGIN{FS=":"; OFS="-"} {print $1,$6,$7}' /etc/passwd

有时候,字段分布没有指定的分隔符.FIELDWIDTHS 变量能处理这种问题

例如:有以下内容

1235.96521
927-8.3652     
36257.8157


$ awk 'BEGIN{FIELDWIDTHS="3 4 3"}{print $1,$2,$3}' testfile


D:\>awk 'BEGIN{FIELDWIDTHS="3 4 3"}{print $1,$2,$3}' myfile
123 5.96 521
927 -8.3 652
362 57.8 157

输出字段为每行3个,并且每个字段长度基于 FIELDWIDTH 的设置

更多变量

  • ARGC 获取传递参数的数量
  • ARGV 获取命令行参数
  • ENVIRON shell 环境变量数组
  • FILENAME awk处理的文件名
  • NF 每行处理的字段数量
  • NR 记录总数
  • FNR 处理的记录
  • IGNORECASE 忽略字符大小写
$ awk 'BEGIN{print ARGC,ARGV[1]}' myfile
2 myfile

获取shell环境变量:

$ awk '
BEGIN{
    print ENVIRON["PATH"]
}'

你可以使用 bash 变量 而不是 ENVIRON 变量:

$  echo | awk -v home=$HOME '{print "My home is " home}'

NF变量指定记录最后一个字段

$ awk 'BEGIN{FS=":"; OFS=":"} {print $1,$NF}' /etc/passwd

NF 变量能被使用作为一个数据字段: $NF

用户自定义变量

你能在shell文件中定义变量如下

$ awk '
BEGIN{
    test="Welcome to LikeGeeks website"
    print test
}'

结构化的命令

if条件语句

testfile 包含如下内容:

10
15
6
33
45


$ awk '{if ($1 > 30) print $1}' testfile

你能用花括号如果想执行更多语句

$ awk '{
    if ($1 > 30)
        {
            x = $1 * 3
            print x
        }
    }' testfile

While 循环

124 127 130
112 142 135
175 158 245
118 231 147

$ awk '{
    sum = 0
    i = 1
    while (i < 5)
    {
        sum += $i
        i++
    }
    average = sum / 3
    print "Average:",average
}' testfile

for循环

$ awk '{
    total = 0
    for (var = 1; var < 5; var++)
    {
        total += $var
    }
    avg = total / 3
    print "Average:",avg
}' testfile

格式化输出

printf 命令允许你打印指定格式的输出

指定格式如下:

%[modifier]control-letter

printf可指定的格式有:

  • c 打印数字作为字符串.
  • d 打印整数值.
  • e 打印科学计数值.
  • f 打印浮点数.
  • o 打印八进制值.
  • s 打印文本字符.
$ awk 'BEGIN{
    x = 100 * 100
    printf "The result is: %e\n", x
}'

内置方法

数学方法

sin(x) | cos(x) | sqrt(x) | exp(x) | log(x) | rand()

$ awk 'BEGIN{x=exp(5); print x}'

字符串方法

$ awk 'BEGIN{x = "likegeeks"; print toupper(x)}'

用户自定义方法

$ awk '     
function myfunc()
{
    printf "The user %s has home path at %s\n", $1,$6

}
BEGIN{FS=":"}
{
    myfunc()

}' /etc/passwd

Python爬取公众号文章

发表于 2018-10-22 | 分类于 Python | | 阅读次数:

chuansong.me收录了很多微信公众号发送的文章,可以从这个网站查找想要爬取的文章。

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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# -*- coding: utf-8 -*-


import requests
from requests.exceptions import RequestException
import re
import time
import json
import random
import os



global count;
count=0;
def get_one_page(url):
#需要加一个请求头部,不然会被网站封禁
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36'}
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status #若不为200,则引发HTTPError错误
response.encoding = response.apparent_encoding
return response.text
except:
return "产生异常"

def mkdir(offset):
global count;
path = os.getcwd()+'\\'+ str(offset)
isExists = os.path.exists(path)
path_csv = path +'\\'+ str(offset)+'.csv'
if not isExists:
os.makedirs(path)
with open(path_csv, 'w', encoding='utf-8') as f:
f.write('链接,标题,日期' + '\n') #注意,此处的逗号,应为英文格式
f.close()
else:
count+=1
print("已下载链接数:",count)
return path

def write_to_file(content, offset):
path = mkdir(offset) +'\\'+ str(offset)+'.csv'
with open(path, 'a', encoding='utf-8') as f: #追加存储形式,content是字典形式
f.write(str(json.dumps(content, ensure_ascii=False).strip('\'\"') + '\n')) #在写入
f.close()

def parse_one_page(html):
pattern = re.compile('<div class="feed_item_question">.*?<span>.*?<a class="question_link" href="(.*?)".*?_blank">(.*?)</a>.*?"timestamp".*?">(.*?)</span>', re.S)
items = re.findall(pattern, html)
return items

def judge_info(name):
url = 'http://chuansong.me/account/' + str(name) + '?start=' + str(0)
wait = round(random.uniform(1,2),2) # 设置随机爬虫间隔,避免被封
time.sleep(wait)
html = get_one_page(url)

pattern1 = re.compile('<h1>Page Not Found.</h1>', re.S)
item1 = re.findall(pattern1, html) # list类型

pattern2 = re.compile('<a href="/account/.*?">(.\d+)</a>(\s*)</span>(\s*?)<a href="/account/.*" style="float: right">下一页</a>')
item2 = re.findall(pattern2, html) # list类型


if item1:
print("\n---------该账号信息尚未收录--------\n")
exit();
else:
print("\n---------该公众号目前已收录文章页数N为:",item2[0][0])


def main(offset, i):
url = 'http://chuansong.me/account/' + str(offset) + '?start=' + str(12*i)
print(url)
wait = round(random.uniform(1,2),2) # 设置随机爬虫间隔,避免被封
time.sleep(wait)
html = get_one_page(url)
for item in parse_one_page(html):
info = 'http://chuansong.me'+item[0]+','+ item[1]+','+item[2]+'\n'
info = repr(info.replace('\n', ''))
#print(info)
#info.strip('\"') #这种去不掉首尾的“
#info = info[1:-1] #这种去不掉首尾的“
#info.Trim("".ToCharArray())
#info.TrimStart('\"').TrimEnd('\"')
write_to_file(info, offset)


if __name__ == "__main__":
print("\n说明:若程序很快退出,可能是输入的信息有错\n"
"\nAuthor:Ctipsy\n")
name = input("请输入公众号名称:")
judge_info(name);
pages = input("\n请输入需要抓取的文章页数(<N):")
for i in range(int(pages)):
main(name, i)

参考链接 https://blog.csdn.net/gonglun7465/article/details/81945271

使用Python将HTML转成PDF

发表于 2018-10-21 | 分类于 Python | | 阅读次数:

主要使用的是wkhtmltopdf的Python封装——pdfkit

1、Install python-pdfkit

1
pip install pdfkit

2、Install wkhtmltopdf

Linux
在wkhtmltopdf下载对应的文件, 解压文件到环境变量所在目录, 例如 /opt 或者 /usr/local/bin 然后在此执行.

Debian / Ubuntu

1
apt-get install wkhtmltopdf

Windows
在wkhtmltopdf下载对应安装包,安装完成后将可执行文件目录加入环境变量.

使用

1
2
3
4
5
import pdfkit

pdfkit.from_url('http://google.com', 'out.pdf')
pdfkit.from_file('test.html', 'out.pdf')
pdfkit.from_string('Hello!', 'out.pdf')

传递url或者文件列表

1
2
pdfkit.from_url(['google.com', 'yandex.ru', 'engadget.com'], 'out.pdf')
pdfkit.from_file(['file1.html', 'file2.html'], 'out.pdf')

传递一个打开的文件

1
2
with open('file.html') as f:
pdfkit.from_file(f, 'out.pdf')

如果你想对生成的PDF作进一步处理, 你可以将其读取到一个变量中:
设置输出文件为False,将结果赋给一个变量

1
pdf = pdfkit.from_url('http://google.com', False)

参考链接
使用Python将HTML转成PDF
python-pdfkit github
wkhtmltopdf安装教程 Installing-wkhtmltopdf

mysql5.7 datetime 默认值为'0000-00-00 00:00:00'无法创建

发表于 2018-10-15 | 分类于 Mysql | | 阅读次数:
1
`create_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00'

mysql5.7设置datetime默认值为 0000-00-00 00:00:00时会报错,[Err] 1067 - Invalid default value for ‘create_date’,这是由于 SQL_MODE 的问题

解决方法

1、查看sql_mode:

1
2
3
4
select @@sql_mode;

//结果
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

NO_ZERO_IN_DATE:在严格模式下,不允许日期和月份为零
NO_ZERO_DATE:设置该值,mysql数据库不允许插入零日期,插入零日期会抛出错误而不是警告。

将NO_ZERO_IN_DATE,NO_ZERO_DATE 去掉之后再次新建表就可以了

1
SET GLOBAL sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

2、改mysql模式
修改my.cnf文件,在[mysqld]中添加

1
sql-mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

3、把语句改为以下就可以执行创建

1
create_date DATETIME NOT NULL DEFAULT '0000-01-01 00:00:00'

PHP微信公众号素材管理

发表于 2018-10-12 | 分类于 公众号 | | 阅读次数:

获取access_token可参考上篇文章 PHP微信公众号开发(一)

本文讲解公众号图文和图片素材的获取

获取素材列表接口文档

接口的地址及参数

1
2
3
4
5
6
7
8
9
10
11
12
13
http请求方式: POST
https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=ACCESS_TOKEN

{
"type":TYPE,
"offset":OFFSET,
"count":COUNT
}

参数 是否必须 说明
type 是 素材的类型,图片(image)、视频(video)、语音 (voice)、图文(news)
offset 是 从全部素材的该偏移位置开始返回,0表示从第一个素材 返回
count 是 返回素材的数量,取值在1到20之间

offset为获取列表的偏移量,count为获取数量(最多每页取20条数据)。因此,我们想要获取全部素材的时候可以获取总素材数量,计算出总页数,循环得到每页偏移量进行分页获取。

获取素材总数接口文档

接口的地址及参数

1
2
3
4
5
6
7
8
9
10
http请求方式: GET
https://api.weixin.qq.com/cgi-bin/material/get_materialcount?access_token=ACCESS_TOKEN

//返回说明
{
"voice_count":COUNT, 语音总数量
"video_count":COUNT, 视频总数量
"image_count":COUNT, 图片总数量
"news_count":COUNT 图文总数量
}

代码示例

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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/**
* 获取素材列表
* @param integer $is_get_all [是否获取全部素材]
* @param integer $offset [全部素材的偏移位置,0表示从第一个素材]
* @param integer $count [返回素材的数量,取值在1到20之间]
* @param string $type [素材的类型,图片(image)、视频(video)、语音 (voice)、图文(news)]
* @return [type] [description]
*/
public function actionBatchMaterial($is_get_all = 0,$offset = 0,$count = 20,$type = 'news'){

$options = array(
'appid'=>$appid, //公众号AppID
'appsecret'=>$appsecret, //公众号AppSecret
);
$this->wechat = new Wechat($options); //此类文件可从参考链接(微信公众平台php sdk)获取

$list_count = 0; //素材数量
if ($is_get_all) { //获取全部素材
$material_count = $this->getForeverCount(); //获取素材总数
if ($material_count) {
switch ($type) {
case 'news':
$list_count = $material_count['news_count'];
break;
case 'image':
$list_count = $material_count['image_count'];
break;
case 'video':
$list_count = $material_count['video_count'];
break;
case 'voice':
$list_count = $material_count['voice_count'];
break;
default:
echo "素材类型错误".PHP_EOL;
exit();
break;
}
}
}

$material_list = [];

if ($is_get_all && $list_count) {
$page = ceil($list_count/$count);//计算总页数
for ($i=0; $i < $page; $i++) { //分页获取素材数据
$foreverList = $this->getForeverList($type,$offset,$count);
if ($foreverList) {
$material_list[] = $foreverList['item'];
}
$offset += $count;//计算下页偏移量
}
}else{ //默认同步最新一页数据
$foreverList = $this->getForeverList($type,$offset,$count);
if ($foreverList) {
$material_list[] = $foreverList['item'];
}
}

}


/**
* [获取图文素材总数]
{
"voice_count":COUNT,
"video_count":COUNT,
"image_count":COUNT,
"news_count":COUNT
}
* @return [type] [description]
*/
private function getForeverCount(){
$count = $this->wechat->getForeverCount();
if (!empty($this->wechat->errMsg) ) {
exit($this->wechat->errMsg);
}

return $count;
}

/**
* 获取素材列表
* @param string $type [素材的类型,图片(image)、视频(video)、语音 (voice)、图文(news)]
* @param integer $offset [全部素材的偏移位置,0表示从第一个素材]
* @param integer $count [返回素材的数量,取值在1到20之间]
* @return [type] [description]
*/
private function getForeverList($type,$offset,$count){
$list = $this->wechat->getForeverList($type,$offset,$count);
if (!empty($this->wechat->errMsg) ) {
exit($this->wechat->errMsg);
}

return $list;
}

[参考链接]

微信公众平台php sdk

PHP微信公众号开发(一)

发表于 2018-10-12 | 分类于 公众号 | | 阅读次数:

一、access_token的使用

获取access_token微信官方文档

access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。

1、建议公众号开发者使用中控服务器统一获取和刷新Access_token,其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致access_token覆盖而影响业务;

2、公众号需要使用AppID和AppSecret调用本接口来获取access_token。并且需要将调用此接口的服务器IP加到微信后台 “微信公众平台-开发-基本配置”的IP白名单中


1
2
3
4
5
https请求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

返回JSON
{"access_token":"ACCESS_TOKEN","expires_in":7200}`

获取的access_token可存储于文件、缓存或数据库中,保存其过期时间,当获取的时候判断是否过期,过期则更新access_token的值。

yii代码示例

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
68
69
70
71
72
73
74
75
class WeChatAccessToken
{

//获取微信Access_Token
public static function getAccessToken()
{
//检测本地是否已经拥有access_token,并且检测access_token是否过期
$accessToken = self::_checkAccessToken();

if($accessToken === false){
$accessToken = self::_getAccessToken();
}

return isset($accessToken['access_token'])?$accessToken['access_token']:'';
}

//从微信服务器获取微信ACCESS_TOKEN
private static function _getAccessToken()
{
$appid = \Yii::$app->params['wechat']['appid'];
$appsecret = \Yii::$app->params['wechat']['appsecret'];

$url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$appid.'&secret='.$appsecret;
$accessToken = Helper::curlGet($url);

$accessTokenArr = json_decode($accessToken,true);
if(!isset($accessTokenArr['access_token'])){
return '';
}
$accessTokenArr['time'] = time();

//缓冲 token
Yii::$app->redis_cache->set('weixin_access_token',json_encode($accessTokenArr),7260);
return $accessTokenArr;
}

//检测微信ACCESS_TOKEN是否过期
private static function _checkAccessToken()
{
$data = Yii::$app->redis_cache->get('weixin_access_token');
$accessToken['value'] = $data;
if(!empty($accessToken['value'])){
$accessToken = json_decode($accessToken['value'], true);

if(time() - $accessToken['time'] < $accessToken['expires_in']-10){
return $accessToken;
}
}
return false;
}
}


class Helper
{
//GET 请求
public static function curlGet($url){
$oCurl = curl_init();
if(stripos($url,"https://")!==FALSE){
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
}
curl_setopt($oCurl, CURLOPT_URL, $url);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
$sContent = curl_exec($oCurl);
$aStatus = curl_getinfo($oCurl);
curl_close($oCurl);
if(intval($aStatus["http_code"])==200){
return $sContent;
}else{
return false;
}
}
}

Docker常用命令

发表于 2018-09-14 | 分类于 Docker | | 阅读次数:

运行一个应用

1
2
3
docker pull nginx

docker run -d -p 8080:80 --name='nginx1' -v /local/html:/usr/share/nginx/html nginx

-d:让容器在后台运行。
-p:将容器80端口映射到宿主机8080端口。

查看正在运行的容器

1
docker ps

使用 docker port 可以查看指定 (ID或者名字)容器的某个确定端口映射到宿主机的端口号

1
docker port 7a38a1ad55c6

查看WEB应用程序日志

1
docker logs -f 7a38a1ad55c6

检查WEB应用程序,使用 docker inspect 来查看Docker的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。

1
docker inspect determined_swanson

停止、启动、删除容器

1
2
3
docker stop determined_swanson   
docker start determined_swanson
docker rm determined_swanson

docker exec :在运行的容器中执行命令

-d :分离模式: 在后台运行

-i :即使没有附加也保持STDIN 打开

-t :分配一个伪终端

在容器mynginx中以交互模式执行容器内/root/runoob.sh脚本

1
docker exec -it mynginx /bin/sh /root/runoob.sh

在容器mynginx中以交互模式执行容器内/root/runoob.sh脚本

1
docker exec -i -t  mynginx /bin/bash
1234
踏浪

踏浪

37 日志
12 分类
13 标签
GitHub
Links
  • yangxianci
© 2019 踏浪
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4
本站访客数 人 本站总访问量 次