streaming json encoder
streaming json encoder是一个PHP库,它提供了一组类,可以以流方式编码JSON,即允许您一点一点地对JSON文档进行编码,而不是一次编码整个文档。与内置的json_encode函数相比,有两个主要优点:
- 例如,您无需将整个数据设置加载到内存中,因为编码器支持在数组和任何类型的迭代器(例如生成器)上进行迭代。
- 您无需将整个结果的JSON文档加载到内存中,因为JSON文档将按值编码值,并且可以按件输出编码的文档。
换句话说,当您需要处理可能占用过多的内存以处理的大型数据集时, streaming json encoder可以提供最大的好处。
为了增加互操作性,该库还提供了一个兼容的流,可与框架和HTTP请求一起使用。
API文档可在以下网址获得:http://violet.riimu.net/api/streaming-json-encoder/
要求
- 最低支持的PHP版本为5.6
- 该库取决于以下外部PHP库:
- psr/http-message(
^1.0)
- psr/http-message(
安装
用作曲家安装
安装此库的最简单方法是使用作曲家来处理您的依赖项。为了通过作曲家安装此库,只需按照以下两个步骤操作:
-
通过在项目root中运行作曲家命令行安装来获取
composer.phar。 -
运行安装脚本后,您应该在项目root中有
composer.phar文件,并且可以运行以下命令:php composer.phar require \"violet/streaming-json-encoder:^1.1\"
通过作曲家安装此库后,您可以通过包括由作曲家在安装过程中生成的vendor/autoload.php文件加载库。
将库添加为依赖关系
如果您已经熟悉如何使用Composer,则可以通过将以下composer.json文件添加到项目中并运行composer install命令来添加库作为依赖项:
{
\"require\" : {
\"violet/streaming-json-encoder\" : \" ^1.1 \"
}
}
手动安装
如果您不希望使用作曲家加载库,则可以通过下载最新版本并将src文件夹提取到您的项目中来手动下载库。然后,您可以包括提供的src/autoload.php文件以加载库类。
请注意,使用作曲家还将自动下载其他必需的PHP库。如果您手动安装此库,则还需要使其他必需的库可用。
用法
该库提供了3种主要的不同方法,可以通过BufferJsonEncoder , StreamJsonEncoder和PSR-7兼容流JsonStream使用库。
使用BufferJsonEncoder
当您需要以不涉及传递回调以处理生成的JSON的方式生成JSON文档时,缓冲区编码器最有用。
使用BufferJsonEncoder最简单方法是将其实例化使用JSON值进行编码,并调用encode()方法以将整个输出返回为字符串:
<?php require \' vendor/autoload.php \' ; $ encoder = new \\ Violet \\ StreamingJsonEncoder \\ BufferJsonEncoder ([ \' array_value \' ]); echo $ encoder -> encode ();
但是,使用此编码器的最有用方法是将其用作迭代器。当编码器实现Iterator界面时,您可以简单地循环使用foreach循环的生成的JSON:
<?php require \' vendor/autoload.php \' ; $ encoder = new \\ Violet \\ StreamingJsonEncoder \\ BufferJsonEncoder ( range ( 0 , 10 )); foreach ( $ encoder as $ string ) { echo $ string ; }
还值得注意的是,编码器支持迭代器的值。更重要的是,也将调用任何传递给编码器的封闭,而将返回值则用作值。上一个示例也可以写为:
<?php require \' vendor/autoload.php \' ; $ encoder = new \\ Violet \\ StreamingJsonEncoder \\ BufferJsonEncoder ( function () { for ( $ i = 0 ; $ i <= 10 ; $ i ++) { yield $ i ; } }); foreach ( $ encoder as $ string ) { echo $ string ; }
附带说明,编码器也将尊重JsonSerializable接口,并将其称为实现接口的对象的jsonSerialize 。
使用streamjsonencoder
流式编码器与BufferJsonEncoder扩展相同的抽象类时的工作原理非常相似。但是,关键区别在于他们如何处理通过JSON输出。
StreamJsonEncoder接受可召唤作为第二个构造函数参数。每当需要输出JSON时,该可调用都会带有两个参数,即输出的实际字符串和输出的令牌类型(这是JsonToken常数之一)。
如果没有传递可可的信息,则StreamJsonEncoder将简单地使用ECHO语句输出JSON。例如:
<?php require \' vendor/autoload.php \' ; $ encoder = new \\ Violet \\ StreamingJsonEncoder \\ StreamJsonEncoder ([ \' array_value \' ]); $ encoder -> encode ();
StreamJsonEncoder中的encode()方法返回传递给输出的字节的总数。此编码器使得以流方式写入JSON,使其方便。例如:
<?php require \' vendor/autoload.php \' ; $ fp = fopen ( \' test.json \' , \' wb \' ); $ encoder = new \\ Violet \\ StreamingJsonEncoder \\ StreamJsonEncoder ( range ( 1 , 100 ), function ( $ json ) use ( $ fp ) { fwrite ( $ fp , $ json ); } ); $ encoder -> encode (); fclose ( $ fp );
使用jsonstream
流类提供了用于流JSON内容的PSR-7兼容StreamInterface 。它实际上使用BufferJsonEncoder来完成艰苦的工作,并简单地将呼叫以流动方式包装。
JsonStream的构造函数要么接受以编码为JSON的值,要么接受BufferJsonEncoder的实例(允许您设置编码选项)。然后,您可以使用PSR-7接口提供的方法在流上操作。例如:
<?php require \' vendor/autoload.php \' ; $ iterator = function () { foreach ( new DirectoryIterator ( __DIR__ ) as $ file ) { yield $ file -> getFilename (); } }; $ encoder = ( new \\ Violet \\ StreamingJsonEncoder \\ BufferJsonEncoder ( $ iterator )) -> setOptions ( JSON_PRETTY_PRINT ); $ stream = new \\ Violet \\ StreamingJsonEncoder \\ JsonStream ( $ encoder ); while (! $ stream -> eof ()) { echo $ stream -> read ( 1024 * 8 ); }
有关PSR-7流的更多信息,请参阅PSR-7文档。
编码器如何解析值
在许多方面, streaming json encoder旨在主要用作json_encode()替换的下降。但是,由于编码器旨在处理大型数据集,因此在处理对象和数组的方式上存在一些显着差异。
首先,要确定如何编码对象,编码器将尝试以以下方式解析对象值:
- 对于实现
JsonSerializable的任何对象,调用了实现的方法jsonSerialize(),而使用返回值。 - 将调用任何
Closure,并将使用返回值。但是,没有以这种方式调用其他调用物。
返回的值是循环的,直到无法进一步解决。之后,对数组还是对象是编码为数组还是对象的决定。使用以下逻辑:
- 以该顺序为0到N-1的任何空数组或数组都编码为JSON数组。所有其他数组均编码为JSON对象。
- 如果对象实现
Traversable实现,并且它要么将Interger0作为第一个密钥返回,要么根本没有返回值,它将被编码为JSON数组(无论其他键如何)。实现Traversable的所有其他对象均编码为JSON对象。 - 任何其他对象,无论是空的还是Mey拥有的任何密钥,都被编码为JSON对象。
但是请注意,如果使用JSON编码选项JSON_FORCE_OBJECT ,则所有对象和数组均编码为JSON对象。
请注意,所有对象均通过foreach语句遍历。这意味着使用迭代器返回的值对所有Traversable对象进行编码。对于其他对象,这意味着使用公共属性(根据默认迭代行为)。
所有其他值(即null,布尔值,数字和字符串)的处理方式与json_encode()完全相同(实际上,它用于编码这些值)。
JSON编码选项
BufferJsonEncoder和StreamJsonEncoder都有一个方法setOptions()来更改JSON编码选项。接受的选项与json_encode()函数接受的选项相同。编码器仍在内部使用json_encode()方法来编码数组或对象以外的其他值。一些选项也对编码器有其他影响:
- 使用
JSON_FORCE_OBJECT将强制将所有数组和对象编码为JSON对象,类似于json_encode()。 - 使用
JSON_PRETTY_PRINT会导致编码器输出空格,以使输出更可读。可以使用方法setIndent()更改所使用的凹痕,该方法可以接受以用作凹痕的字符串参数或用于指示空格数量的整数。 - 使用
JSON_PARTIAL_OUTPUT_ON_ERROR即使编码错误,也会导致编码器继续输出。否则,编码将停止,编码器将抛出一个EncodingException。
学分
该图书馆是版权(C)2017-2022 RiikkaKalliomäki。
有关许可证和复制信息,请参见许可证。
