dotink / jin
Jsonified Ini Notation
Requires
- php: >=5.4.0
- adbario/php-dot-notation: ^2.5
Requires (Dev)
- dotink/lab: ^1.1
- dotink/sage: ^1.0
- phpunit/phpunit: ^7.4
README
JIN 是一种数据格式,它使用与 JSON 类似的 INI 文件结构。
它是一种简单、非正式的语言,非常适合配置数据和设置。它最好用作元配置或某种类型的模式配置,但也可以为像 .env
文件这样的简单内容提供丰富的类型和对象支持。
在某种程度上,它与 TOML (https://github.com/toml-lang/toml) 类似,但没有正式规范。解析规则可以最好地描述如下
- 文件结构类似于 INI 文件
- key = value
- [section]
- ; comment
- 值类似于 JSON,但有以下不同
- 不支持转义字符,例如 \n, \b, \t
- 单个 \ 不需要转义
基本用法
$jin_parser = new Dotink\Jin\Parser() $jin_string = file_get_contents('config.jin'); $config_data = $jin_parser->parse($jin_string)->get();
在集合上调用 get()
将返回作为关联数组的完整解析数据。
如果您想直接与集合一起工作,可以省略 get()
。您可以在 (https://github.com/adbario/php-dot-notation) 查看有关集合的更多文档。
$config = $jin_parser->parse($jin_string);
直接使用集合将允许您使用“点表示法”引用和检索特定值,如果它们不存在,还可以提供默认值
$config->get('database.connections.default', [ 'name' => 'website', 'host' => 'localhost', 'user' => 'web', 'pass' => '3ch0th3w4lRUS' ]);
您还可以通过将第二个参数传递为 FALSE 来在解析的 JSON 中保留 stdClass
对象
$config_data = $jin_parser->parse($jin_string, FALSE)->get();
语言
简单字段
field = value ; INI style string
字符串不必加引号,但也可以加
field = "value" ; JSON style string
整数会自动转换为正确的类型
integerValue = 1
浮点数也是如此...
floatValue = 1.03
布尔值和 NULL 值不区分大小写
boolValue = false
boolValue = TRUE
nullValue = NULL
多行文本
multi = JIN supports multi-line values until the new line resembles an INI database structure. So, for example, this line would be parsed with new lines preserved until `foo=bar` or `[section]` or `\n\n`.
注释
注释可以在值的任何位置允许,因此请记住,任何在 ;
字符之后的内容都将被截断。
field = "This probably does not do what you expect; this is stripped"
类似于 JSON 的值
数组以字面量定义
favoriteFoods = ["Tacos", "Sushi", "Curry"]
对象也以字面量定义
favorites = {"food": "Indian", "music": "Classic Rock"}
两者都可以跨越多行并包含注释
multiFoods = [ "Tacos", "Sushi", ; Most keto friendly "Curry" ] multiFavorites = { ; ; The basics ; "food": "Tacos", "music": "Classic Rock" ; Not actually my favorite }
差异
虽然值类似于 JSON,但严格来说,它们不是 JSON。主要区别是它们不支持 JSON 的内置转义字符,因此您不能使用 \n
或 \t
。另一方面,您不需要转义反斜杠
middlewares = [ "App\Middleware\ResponseHandler" ]
部分
部分提供了对 JSON 对象结构的替代方案。请注意,部分永远不会解析为 stdClass
对象,但总是返回关联数组。
[category] fieldOne = valueOne fieldTwo = valueTwo fieldThree = 1 fieldFour = [0, 7, 9, 13] fieldFive = { "foo": "bar" }
子部分
您可以通过用点分隔前一个类别名称来添加子部分。这对于具有重复数据的键配置值非常有用,例如,想象一个具有多个别名连接的数据库配置
[database] [database.connections.default] driver = pgsql dbname = website host = localhost [database.connections.forums] driver = mysql dbname = forums host = localhost user = web pass = 3ch0th3w4lRUS
部分引用
您可以通过简短的部分名称来引用父部分。
[database] [&.connections.default] driver = pgsql dbname = website host = localhost
可以堆叠引用以引用子子部分。引用堆叠始终从最后一个未引用定义的部分开始
[database] [&.connections] ; ; This section contains all of our database connections ; [&&.default] driver = pgsql dbname = website host = localhost
环境变量
您可以获取环境中的值。
envField = env(DEBUGGING)
并提供默认值,当它们未设置时
envField = env(DEBUGGING, TRUE)
本地语言值
您可以使用本地语言函数(在本实现中为 PHP)
runField = run(md5('hash this thing'))
您还可以为解析器添加上下文以访问变量
$jin_parser = new Dotink\Jin\Parser([ 'app' => $app ]);
然后像您预期的那样访问/使用它们
cacheDirectory = run($app->getDirectory('storage/cache', TRUE))
自定义函数
您可以通过将函数名键的调用来作为第二个参数传递给解析器来添加自定义函数
$jin_parser = new Dotink\Jin\Parser([], [ 'hello' => function($name) { return 'Hello ' . $name; } ]);
然后像您预期的那样使用它们。
hello = hello(Matt)
注意,您可以重载 env()
和甚至 run()
函数,但是重载如 map()
、def()
、inc()
这样的结构将不会工作。
模板
模板提供了一种强大的方式来重复具有不同值的复杂数据结构
[database] settings = def(type, name, host, user, pass) { { "type": $type, "name": $name, "host": $host, "auth": { "user": $user, "pass": $pass } } } [&.connections] default = inc(database.settings) { pgsql my_database localhost ; ; Do not be afraid to use any valid value where values are ; specified ; env(DB_USER, web) env(DB_PASS, NULL) }
模板还可以用来创建非键控对象的数组
[routing] route = def(methods, pattern, target) { { "methods": $methods, "pattern": $pattern, "target": $target } } ; ; The map function takes a tab separated list of values. Multiple tabs ; are reduced to one before parsing. ; routes = map(routing.route) { ["GET"] / ViewHome ["GET"] /articles ListArticles ["POST"] /articles CreateArticle ["GET"] /articles/{id} ViewArticle ["POST"] /articles/{id} EditArticle }
测试
php vendor/bin/phpunit --bootstrap vendor/autoload.php test/routines/
附录
JIN最初被编写为配置数据映射ORM的一种方式。它是一种非常灵活且直观的语言,但在某些情况下可能没有意义。强烈建议如果您经常使用它进行访问配置(如运行时),则应将结果集合序列化和缓存,而不是每次加载时都解析它。
编辑器支持
这里有一个为Atom准备的语法文件,可以在这里找到
https://github.com/dotink/atom-language-jin
由于其与TOML的相似性,TOML语法高亮也往往看起来不错。您还可以尝试JS/JSON语法高亮,但具体效果可能因语法高亮实现而异。