#273 PHP 5.2 与 PHP 5.3+ 的几处差异
PHP 2018-11-22修改一个我之前开发的一个 Discuz 插件对于 PHP 5.2 的支持(当时插件开发环境是 PHP 5.6.37),发现以下几处需要注意的地方:
coding in a complicated world
修改一个我之前开发的一个 Discuz 插件对于 PHP 5.2 的支持(当时插件开发环境是 PHP 5.6.37),发现以下几处需要注意的地方:
将数据通过编码存在图片里面,实现导出导入功能。
虽然我不知道什么场景下需要使用这个方案,但这个想法特有意思。
纯英文:
中文:
以下是几个大版本和发布时间,作为一个大概的时间线吧:
2009/12 1.2
2010/03 1.4
2010/08 1.6
2011/03 1.8
2011/09 2.0
2012/08 2.2
2013/03 2.4
2014/04 2.6
2015/03 3.0
2015/12 3.2
2016/11 3.4
2017/11 3.6
2018/06 4.0
当前最新版本 8 月发布的 4.0.2
Update @ 2021/06/07:
之后主版本号就一直停在了 4,2020 年之后甚至一直停在了 4.4(2019 年 4.2,2020 年 4.4),这也意味着功能组件稳定下来了。
在 Mongo 中,有一些名词变了,看文档的时候需要注意。
数据库 Database,索引 Index 不变。
String
UTF-8 类型Int32
Long
Double
Boolean
Object
Array
Date
ObjectId
Null
Date
Timestamp
Decimal128
MinKey
MaxKey
Binary data
JavaScript
废弃:
所有 Document 必须有一个 _id
键,没有类型限制,默认是 ObjectID 类型。
PS:所有 Document(BSON)中还包含一个时间戳,4B 时间戳 + 4B 自增数
在大数据时代,传统 RDB 十分严谨的同时,效率也十分低下。
有人创造了 NoSQL 这个词,表示 Non-SQL,即不支持 SQL 的数据库。
后来部分产品添加了 SQL 支持,含义又演化成 Not Only SQL。
再后来又有人提出 NewSQL 概念,还是差不多的意思。
实现方式:
什么事情是 MongoDB 可以做,而 MySQL / PostgreSQL 不能做的?
PS:由于和云服务提供商的斗争,4.1.4 之后的所有版本(还有老版本的 BUG 修复版本)全部改用 SSPL (Server Side Public License,服务器端公共许可证) 。
该协议要求云服务提供商必须使用相同协议开放代码(之前所有主要的开源协议都没有对云服务提供商做任何限制),但 OSI 拒绝承认这是开源协议,部分 GNU/Linux 发行版将其从软件源移除。
再后来,其他开源项目,比如 Redis,Elastic,Graylog,也相继采用了和 MongoDB 相同的策略,改用了新的协议分发代码以对抗云服务提供商。
sudo apt install -y mongodb
sudo systemctl disable mongodb
sudo systemctl restart mongodb
sudo systemctl status mongodb
如果希望直接从官方安装最新版本(仅支持 Ubuntu LTS 版本):
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4
echo "deb [arch=amd64] https://repo.mongodb.org/apt/ubuntu/dists/$(lsb_release -cs)/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb44.list
sudo apt update
sudo apt install -y mongodb-org
# sudo apt-mark hold mongodb-org # 避免随系统更新
PS:较老的版本有一个自带的简易 Web UI,通过 httpinterface, 或者 rest 参数可以启动,3.2 之后去掉了。
# 自带配置
dbpath=/var/lib/mongodb
logpath=/var/log/mongodb/mongodb.log
logappend=true
bind_ip = 127.0.0.1 # 修改为 0.0.0.0
# 端口是默认的 27017
journal=true
# 添加配置
replSet = markjour
# daemon 模式运行,如果用 systemd 就不需要这一行:
fork = true
sudo systemctl restart mongodb
sudo ps -ef | grep mongod
sudo netstat -antp | grep mongod
// 主节点初始化
rs.initiate();
// 查看副本集配置
cfg = rs.conf();
// 修改主节点 host 为 IP 形式
cfg.members[0].host = "<IP>:<Port>";
rs.reconfig(cfg);
// 添加从节点
rs.add("192.168.64.234");
// 如果是连接不上的节点:"Quorum check failed because not enough voting nodes responded; required 2 but only the following 1 voting nodes responded: 172.16.0.49:27017; the following nodes did not respond affirmatively: 192.168.64.234:27017 failed with Couldn't get a connection within the time limit"
rs.remove("192.168.64.234"); // 移除节点
客户端 SHELL 是基于 JavaScript 的。
mongo
show dbs
db
use <dbName>
db.createCollection("s1", {capped:true, size:100000})
保留数据库名称:admin, config, local
https://www.mongodb.com/docs/manual/reference/connection-string/
mongodb://
[username:password@]
host1[:port1]
[,host2[:port2],...[,hostN[:portN]]]
[
/[database]
[?options]
]
Terminal 终端
SMC 短信中心
SMS GW 短信网关
受协议限制,短信内容最大 140 字节,所以:
采用 8bit 编码的话,最长 140 字符。
采用 7bit 编码的话,最长 160 字符(正好)。
采用 UCS2 编码的话,最长 70 字符。
如果涉及长短信切割,根据通行的拓展协议,需要采用头三个字节存储相关信息。
采用 8bit 编码的话,每段最长 137 字符。
采用 7bit 编码的话,每段最长 156 字符(最后剩余 4 bits 空着)。
采用 UCS2 编码的话,每段最长 67 字符。
参考 GSM 03.40 9.2.3.24 TP-User Data (TP-UD) 部分,一般有两种方案:
\x05 剩余协议头长度
\x00 短信标识 GSM 03.40
\x03 剩余短信标识长度
随机字节(1 字节)
总包数
包序号(1 开始)
还有一种没有怎么见过的方案,就是采用两个字节做随机标识,然后头三字节改成 \x06\x08\x04
。
第二字节叫做 The Information Element Identifier(信息元素标识符),上面的 \x00
,\x08
分别标识 1 字节,2 字节随机标识方案。其他值可以参考文档。
from tornado import gen, ioloop
@gen.coroutine
def dosth():
yield gen.sleep(1)
print('slept for 1 second')
ioloop.IOLoop.current().run_sync(dosth)
from tornado import gen, ioloop
@gen.coroutine
def dosth():
print('dosth 222222222222222222222')
yield gen.sleep(1)
print('slept for 1 second 22222222')
print('dosth over 2222222222222222')
@gen.coroutine
def test():
print('test 111111111111111')
dosth()
print('test over 1111111111')
print('start')
ioloop.IOLoop.current().run_sync(test)
print('over')
# start
# test 111111111111111
# dosth 222222222222222222222
# test over 1111111111
# over
# start
# test 111111111111111
# dosth 222222222222222222222
# test over 1111111111
# slept for 1 second 22222222
# dosth over 2222222222222222
# over
git diff
对应 diff
命令git apply
对应 patch
命令git diff v1.2.1 v1.2.2 > v1.2.1_v1.2.2.patch
git apply --check v1.2.1_v1.2.2.patch
git apply -v --whitespace=warn v1.2.1_v1.2.2.patch
有部分文档中说 git apply
和 patch
在一些细节上实现不一致,需要留意。但我轻量级使用,没有遇到过什么问题。
假设:
aaa@163.com
,B 的邮箱地址是 bbb@163.com
,C 的邮箱地址是 ccc@qq.com
。那么:
smtp.163.com
mx.qq.com
,然后将邮件投递过去(SMTP)。pop3.163.com
下载了邮件(POP3),手机自带的邮件客户端配的 imap.163.com
,那就走 IMAP 协议。163 | ||||
---|---|---|---|---|
SMTP | smtp.qq.com | 465/587 | smtp.163.com | 25, 465/587 |
POP3 | pop.qq.com | 995 | pop.163.com | 110, 995 |
IMAP | imap.qq.com | 993 | imap.163.com | 143, 993 |
可以看到各种 MxA:
vscode 或者 Typora 或这其他的一些编辑器都支持在 Markdown 中使用数学公式,直接预览就行了。
但是如果是自己做 Markdown 转换,生成 HTML 页面,就必须做点额外的工作。
我发现 Mathjax 挺好用的,只需加入三行:
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script
src="https://cdn.jsdelivr.net/npm/mathjax@3.0.1/es5/tex-mml-chtml.js"
async
></script>
<script>
MathJax = {
tex: {
inlineMath: [
["$", "$"],
["\\(", "\\)"],
],
},
};
</script>
Katex 据说不错,以后如果发现 Mathjax 有不足之处再试试。
Update @ 2022-05-27: 根据 May 19, 2022 的博客 Render mathematical expressions in Markdown, GitHub 开始采用 Mathjax 渲染数学公式。
数学公式的语法都是参考 LaTeX(2019/07/21, LaTeX)。
CURRENT_PATH=$(dirname $(readlink -f "$0"))