benmajor / jql
用于JSON文件和字符串的查询语言,由PHP构建
Requires
- php: >= 5.6.0
This package is auto-updated.
Last update: 2024-08-29 05:18:27 UTC
README
JSON查询语言(JQL - 发音为 "jackal")是一个用PHP编写的查询语言系统,用于查询JSON字符串和文件。它还支持PHP stdClass 对象。这种“语言”在SQL(流行的数据库查询语言)的基础上构建,以便于采用和学习,但确实有一些限制,因为SQL的一些高级功能无法实现。
在阅读完整文档之前,请查看最小示例,以更好地理解如何使用JQL。
目录
1. 安装
安装JQL库的最简单方法是使用Composer。要将JQL添加到您的项目中,只需从终端运行以下Composer命令
$ composer require benmajor/jql
或者,从存储库的src/目录下载所有源文件,并将它们包含到您的项目中。
2. 使用
JQL旨在让网页开发者易于使用;其语法基于SQL,尽管功能更有限,但结果符合预期。目的是构建一个简单高效的JSON和PHP数据结构的查询语言。使用相对简单直接,但建议查阅示例,以从JQL中获得最佳结果。
要开始,只需使用数据集调用JQL构造函数。构造函数接收单个参数,可以是以下任何一种
- JSON编码的字符串
- 包含文件指针的字符串
- PHP对象数组
例如,以下所有构造函数都是有效的
使用JSON编码的字符串
$jql = new JQL('[{ 'id': 2, 'name': 'John', 'surname': 'Doe' }]');
指向有效JSON文件的指针
$jql = new JQL('MyDataset.json');
PHP对象数组 / 关联数组
$jql = new JQL([ [ 'id' => 1, 'name' => 'John', 'surname' => 'Doe' ] ]);
构造函数将返回一个新的JQL对象,可以对其执行函数,或者您也可以对数据执行类似SELECT的查询,返回特定列,并按特定数量和/或偏移量排序结果。以下部分将提供选择、更新、排序和限制数据的详细信息。
选择特定列
创建JQL对象后,您应调用select()方法来从JSON数据请求特定列。
应指定多个字段为数组,但您始终可以通过将包含*的字符串传递给select()函数来请求所有字段,如下所示
$jql->select( '*' );
或者,您可以通过将它们作为数组传递来指定要检索的特定列
$jql->select([ 'name', 'surname' ]);
上述代码将只返回指定数据集中每个对象的name和surname字段。
除了返回特定的列之外,JQL 还内置了可以在选择之前调用在字段上的函数。JQL 的多数内置函数都是基于 SQL 函数,并且以类似的方式工作。遗憾的是,由于 SQL 的复杂性以及本库旨在保持快速和高效的宗旨,无法在一次数据遍历中调用多个函数。
以下是一个使用两个函数调用的 select() 例子
$jql->select([ 'LCASE(name) AS name_lower', 'CURRENT_TIMESTAMP() AS timestamp' ]);
有关函数和例子的完整列表,请参阅本文档的 函数参考 部分。
JQL 还能够返回字段别名,这可以通过使用 AS 关键字实现。当你需要用比原始列名更短的引用来引用字段时,这特别有用。例如,在上面的代码片段中,name_lower 是一个不存在于原始数据结构中的别名字段。别名也可以不用函数使用,例如
$jql->select([ 'super_long_column_name AS id' ]);
更新特定列
除了选择字段外,JQL 还能够更新原始数据结构中的字段。这是通过使用 update() 方法实现的,该方法与 where() 方法(详情请见)结合使用时特别有用。
$jql->update([ 'name' => 'NAME REPLACED' ]);
JQL 还具有在更新列时可以使用的内置函数。有关使用 update() 方法时可以使用的函数的详细信息,请参阅 函数参考。
使用 where() 搜索数据
where() 方法的工作方式类似于 SQL 的 WHERE 子句,可以用来快速筛选 select() 或 update() 方法的结果。
where() 方法接受一个由 AND 或 OR 分隔的单独的条款字符串。截至撰写本文时,JQL 不支持组合条款,如 AND 和 OR,只能使用其中一个。
为了筛选所有 age 列值 > 10 的记录,我们可以使用
$jql->select('forename')->where('age > 10');
JQL 支持以下操作符与 where() 方法一起使用
排序结果
JQL 能够根据指定的列值对数据进行排序。可以使用多个列进行排序,并且可以指定每个列的顺序,如下所示
$jql->select('forename')->order('surname', 'ASC');
上述代码片段将按 surname 列的值升序排序结果。可以通过将多个列添加到 order() 中来排序数据,例如,要按 surname 升序和 age 降序排序,我们可以执行以下操作
$jql->select('forename')->order('surname', 'ASC')->order('age', 'DESC');
限制结果
我们还可以使用 limit() 限制结果的数量,与 offset() 结合使用时特别强大。例如,以下代码片段只检索前两个匹配的记录
$jql->select('forename')->where('age > 10')->limit(2);
还可以将偏移量指定为 limit() 方法的第二个参数。例如,以下代码片段将返回 2 个结果,第一个结果将被跳过
$jql->select('forename')->where('age > 10')->limit(2, 1);
您还可以使用 offset() 方法单独指定偏移量,如下所示(以下代码片段与上面显示的代码片段相同)
$jql->select('forename')->where('age > 10')->limit(2)->offset(1);
执行查询
一旦使用 select() 和 update() 方法设置完查询,就可以实际执行查询了。这可以通过 JQl 中的一系列函数来实现,具体取决于所需的查询结果。
fetch():fetch() 方法将返回一个包含所有结果匹配项的数组,限制在指定的限制和偏移量内,并按指定的列排序。如果没有找到匹配项,则该函数返回 NULL。
fetchOne():fetchOne() 方法将返回匹配集的第一条结果。它将以对象的形式返回,而不是数组。如果没有找到匹配项,则该函数返回 NULL。
fetchAsJSON( $prettyPrint = false ):fetchAsJSON 方法与 fetch() 相同,但它返回一个 JSON 编码的字符串,而不是 PHP 数组。此函数接受一个参数,可以用来指定返回的 JSON 是否是格式化的(默认为 false)—— 必须是一个有效的布尔值。
fetchOneAsJSON():
与上述相同,但针对第一条记录。
saveAsFile( $pointer ):
将结果数据保存到位于 $pointer 的 JSON 文件中。
count():
简单返回表示受影响行数的整数。
3. 函数参考
所有函数都可以在 JSON 结构中出现的列或固定字符串(类似于 SQL)上调用。例如,以下两个都会产生相同的结果
$json = [ [ 'id' => 1, 'forename' => 'John', 'surname' => 'Doe' ] ]; $jql = new JQL($json); $jql->select([ 'UPPER(forename)' ]); # Returns JOHN for the first record. $jql->select([ 'UPPER(John)' ]); # Returns JOHN for ALL records.
select() 函数
以下函数可以与 select() 方法一起使用
字符串函数
数字函数
日期函数
聚合函数
update() 函数
以下函数可以与 update() 方法一起使用
APPENDCONCAT_WSLCASELEFTLOWERLPADLTRIMPREPENDREPLACEREVERSERIGHTRPADRTRIMSUBSTRSUBSTRINGTRIMUCASEUPPER
6. 本地化
JQL 可以返回服务器的当前日期和时间,以及日期的月份和日名称。因此,它已经开发了一些内置的本地化选项,这些选项有助于处理多语言应用程序。如果您需要其他语言的月份和日名称,必须首先调用 setLocale() 方法
$jql->setLocale('nl_NL');
上面的代码将当前区域设置设置为 nl_NL。
要处理时间函数的不同时区,只需调用 setTimezone() 并指定所需的时区
$jql->setTimezone('Europe/Paris');
5. 示例
本节包含一些示例,演示了 JQL 的使用方法。如果在您的编码过程中发现任何函数没有按预期工作,请通过 Github 存储库提出问题。
以下所有示例都假设以下 JSON 结构
[
{
'id': 1,
'forename': 'John',
'surname': 'Doe',
'age': 25,
'birthday': '1995-05-24',
'tags': [ 'red', 'green' ]
},
{
'id': 2,
'forename': 'Joe',
'surname': 'Bloggs',
'age': 50,
'birthday': '1955-02-24',
'tags': [ 'red', 'blue' ]
},
{
'id': 3,
'forename': 'Foo',
'surname': 'Bar',
'age': 12,
'birthday': '2007-12-09',
'tags': [ ]
},
{
'id': 4,
'forename': 'John',
'surname': 'Boy',
'age': 19,
'birthday': '2018-09-09'
}
]
最小工作示例
选择每个用户的姓名和姓氏,按姓氏和名字排序
$jql = new JQL($json); $jql->select([ 'forename', 'surname' ]) ->order('surname', 'ASC') ->order('forename', 'ASC') ->fetch();
使用函数
通过连接他们的 forename 和 surname 字段来返回每个用户的完整姓名
$jql = new JQL($json); $jql->select([ 'CONCAT_WS(forename, surname, \' \') AS full_name' ]) ->fetch();
使用聚合函数
获取所有用户的平均年龄
$jql = new JQL($json); $jql->select([ 'AVG(age) AS average_age' ]) ->fetchOne();
使用 where()
检索标记为 red 的所有用户的平均年龄和连接的完整姓名
$jql = new JQL($json); $jql->select([ 'AVG(age) AS average_age', 'CONCAT_WS(forename, surname, \' \') AS full_name' ]) ->where('tags CONTAINS red') ->fetch()
更新记录
将用户 1 更新为包含完整姓名的新字段,并将更新后的结果保存到名为 updated.json 的 JSON 文件中
$jql = new JQL($json); $jql->update([ 'full_name' => 'CONCAT_WS(forename, surname, \' \') AS full_name' ]) ->where('id = 1') ->saveAsFile('updated.json');
日期函数
选择用户出生的日期,这些用户被称为 John 并且年龄大于 18
$jql = new JQL($json); $jql->select([ 'DAYNAME(birthday) AS birth_day' ]) ->where( 'forename = John AND age > 18' ) ->fetch();
6. 需求
JQL 是自包含的,没有外部库或框架依赖。但是,为了正常工作,以下是最小的 PHP 要求:
- PHP 版本 >= 5.6
- 启用 PHP
json模块
7. 路线图
JQL 仍在开发中,有许多功能我打算添加到库中。如果您想为项目做出贡献,请与我联系!
- 支持远程 JSON 文件
- 支持多种 WHERE 子句类型(包括
AND和OR)
8. 许可证
MIT 许可证
版权所有 (c) 2019 Ben Major
特此授予任何获得本软件及其相关文档副本(以下简称“软件”)的人免费使用的许可,不受限制地处理该软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件的副本,并允许向提供软件的人做此类事情,但需遵守以下条件:
上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。
软件按“原样”提供,不提供任何形式的保证,明示或暗示,包括但不限于对适销性、适用于特定目的和无侵犯性的保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任负责,无论该责任是基于合同、侵权或其他原因,无论该索赔、损害或其他责任是否源于、源于或与软件或软件的使用或其他交易有关。