因为后台接口大体都是使用json的,所以在openrsty的lua脚本中,常需要做json的相关处理。Lua cjson 就是一个用于处理json的lua模块。Openresty 默认是已经安装了cjson的,但是本着学习的态度,还是决定在本地的lua环境下安装和使用。本文将会介绍 lua cjson 基于标准 lua 和 luajit,在linux和mac的安装及简单的使用。
内容没啥难度,只不过在linux和mac,以及lua和luajit间稍微有点差别,自己整的时候刚开始也有点不清楚,所以特别记录一下,防止以后再次踩坑。

lua环境安装

首先,肯定需要安装lua运行时环境:标准lua或者luajit,可以参考lua安装小记 安装。

注意:在笔者写改文章的时候,lua-cjson并不支持lua5.3版本,只支持lua5.1、lua5.2和luaJIT。

这也是我遇到的一个坑,以为是安装出错了。使用的时候会出现以下的错,换成lua5.2就可以了。

1
dlopen(/usr/local/lib/lua/5.3/cjson.so, 6): Symbol not found: _lua_insert

标准lua

标准lua安装很简单,下载,编译安装即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
// 下载
curl -R -O http://www.lua.org/ftp/lua-5.3.3.tar.gz
// 解压
tar zxf lua-5.2.4.tar.gz
cd lua-5.2.4
//linux下编译
make linux test
// mac os
make macosx test
//安装
sudo make install

这样lua就安装好了,验证一下。

1
2
$ lua -v
Lua 5.2.4 Copyright (C) 1994-2016 Lua.org, PUC-Rio

luajit

luajit的安装也和lua一样。

1
2
3
4
5
6
7
8
//下载
git clone http://luajit.org/git/luajit-2.0.git
tar zxf LuaJIT-2.0.4.tar.gz
cd LuaJIT-2.0.4
//编译
make
//安装
sudo make install

验证安装成功。

1
2
$ luajit -v
LuaJIT 2.0.4 -- Copyright (C) 2005-2016 Mike Pall. http://luajit.org/

lua cjson 安装

这样lua就安装完成了,接着安装lua cjson。可以直接到官网github上下载源码。

1
2
3
4
// 通过wget下载
$ wget https://www.kyne.com.au/~mark/software/download/lua-cjson-2.1.0.tar.gz
// 通过git下载
$ git clone git@github.com:mpx/lua-cjson.git

下载解压后,编译需要根据自己的lua环境以及操作系统修改Makefile的一些配置,不然容易出错。
以下是Makefile中的一些配置。

1
2
3
4
5
6
7
8
LUA_VERSION = 5.2
TARGET = cjson.so
PREFIX = /usr/local
CJSON_LDFLAGS = -shared
LUA_INCLUDE_DIR = $(PREFIX)/include
LUA_CMODULE_DIR = $(PREFIX)/lib/lua/$(LUA_VERSION)
LUA_MODULE_DIR = $(PREFIX)/share/lua/$(LUA_VERSION)
LUA_BIN_DIR = $(PREFIX)/bin

最终生成的文件是cjson.so。LUA_VERSION为lua的版本。LUA_INCLUDE_DIR为一些编译用的头文件路径。LUA_CMODULE_DIR是最后cjson.so安装的路径。
在macos环境下,需要修改CJSON_LDFLAGS。Makefile中注释也有介绍,如下:

1
CJSON_LDFLAGS = -bundle -undefined dynamic_lookup

不然会出现以下错误。

1
ld: symbol(s) not found for architecture x86_64

对于luajit环境,也要修改相关版本和路径。luajit的lua版本为5.1。我用luaJIT2.0的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
LUA_VERSION = 5.1
TARGET = cjson.so
PREFIX = /usr/local
#CFLAGS = -g -Wall -pedantic -fno-inline
CFLAGS = -O3 -Wall -pedantic -DNDEBUG
CJSON_CFLAGS = -fpic
#CJSON_LDFLAGS = -shared
CJSON_LDFLAGS = -bundle -undefined dynamic_lookup
LUA_INCLUDE_DIR = $(PREFIX)/include/luajit-2.0
LUA_CMODULE_DIR = $(PREFIX)/lib/lua/$(LUA_VERSION)
LUA_MODULE_DIR = $(PREFIX)/share/lua/$(LUA_VERSION)
LUA_BIN_DIR = $(PREFIX)/bin

配置好后,make install安装,就会将生成的cjson.so 复制到LUA_CMODULE_DIR目录下,并修改755权限。

1
2
3
4
$ sudo make install
mkdir -p //usr/local/lib/lua/5.3
cp cjson.so //usr/local/lib/lua/5.3
chmod 755 //usr/local/lib/lua/5.3/cjson.so

这样lua cjson就可以使用了。

使用

要使用json功能,在lua脚本中引入cjson模块即可。

1
2
local cjson = require("cjson");
local cjson_safe = require("cjson.safe")

两者功能差不多,只不过前者在json转码过程有错会立即报错,而后者会返回nil和一条错误信息。

encode

encode用于将lua值或表转化为一个json字符串。

1
2
3
4
5
6
7
8
9
10
11
local cjson = require "cjson";
local obj = {
name = "dennis",
age = 18
};
local jsonStr = cjson.encode(obj);
print(jsonStr);
-- 输出:{"name":"dennis","age":18}

decode

encode用于将json字符串能转化为一个lua 值或者表。

1
2
3
4
5
6
7
8
9
10
11
local cjson = require"cjson";
local jsonStr = '{"name":"dennis","age":18}';
local luaObj = cjson.decode(jsonStr);
print(luaObj.name);
print(luaObj.age);
--输出
dennis
18

这里遇到个有趣的坑,就是关于require的规则。因为我开始写这个lua测试文件的时候,文件命名为cjson.lua。一直出错,我总怀疑是安装错误了。后来修改了文件名,就好了。原来lua脚本中require的时候会现在本地路径查找,再到module库里查找。所以引用本地的cjson的时候就出错了。

总结

本文主要介绍lua cjson的安装和使用。首先介绍了lua和luaJIT在linux和mac的安装。然后介绍了基于lua、luaJIT,在不同操作系统的配置和编译安装。最后介绍了lua cjson的使用。

参考

[1] Lua CJSON 2.1.0 Manual
[2] luajit 安装cjson
[3] lua安装小记
[4] Lua 使用cjson解析json数据(Mac环境)