此包已被废弃,不再维护。未建议替代包。

PHP的JSON解码器和编码器,完全遵循RFC 7159的Unicode支持。除了UTF-8,它还支持UTF-16BE、UTF-16LE、UTF-32BE和UTF-32LE编码。此外,根据RFC的建议,它还可以在解析JSON时忽略字节顺序标记(BOM)。

v1.0.1 2016-11-10 17:31 UTC

This package is not auto-updated.

Last update: 2020-02-07 07:38:56 UTC


README

Author Quality Score Software License Packagist Version Total Downloads Build

简介

此库提供了一个基于原生PHP json_* 函数的JSON解码器和编码器,但具有完全的Unicode支持,遵循RFC 7159

原生PHP函数仅支持UTF-8编码且不包含字节顺序标记(BOM)的JSON字符串。

此库封装了PHP函数,并允许您使用RFC允许的以下附加编码解码和编码JSON文件

  • UTF-16BE
  • UTF-16LE
  • UTF-32BE
  • UTF-32LE

默认情况下(可以禁用)它还会忽略字节顺序标记(BOM),如RFC中“为了互操作性”所建议的。

安装

您可以使用Composer安装此库。通过命令行界面...

$ composer install crossjoin/json

或将以下要求添加到您的composer.json文件中

{
    "require": {
        "crossjoin/json": "^1.0.0"
    }
}

要求

此库支持以下PHP版本(版本越高,对JSON的支持越好)

  • PHP >= 5.3.3
  • PHP >= 7.0.0
  • HHVM(使用版本3.6.6测试过)

以下扩展之一是必需的,以支持不同于UTF-8的不同编码

  • iconv
  • mbstring
  • intl(只能与PHP >= 5.5.0一起使用)

用法

解码

它是如何工作的?

首先检查JSON字符串是否有字节顺序标记和使用的编码。如果存在字节顺序标记,则从JSON字符串中删除。如果使用的是UTF-8之外的编码,则将JSON字符串的编码更改为UTF-8。

最后调用原生的json_decode()函数来解码修改后的JSON字符串,因此结果依赖于原生PHP函数(并且可能在不同版本的PHP之间有所不同)。

所有返回的数据都编码为UTF-8,因此您可以在PHP中使用它。

基本示例

使用Crossjoin\Json命名空间中提供的函数的基本示例

<?php
// From PHP 5.6.0 you can also use namespaced functions to avoid the namespace
// prefixes below.
//use function \Crossjoin\Json\json_decode, \Crossjoin\Json\json_encode;
//use function \Crossjoin\Json\json_last_error, \Crossjoin\Json\json_last_error_msg;

// Decode example (same arguments as the native PHP function).
//
// Note: If an invalid type is used for one of the arguments, a
// \Crossjoin\Json\Exception\InvalidArgumentException exception is thrown,
// while the native PHP function may accept some of them.
$data = \Crossjoin\Json\json_decode('{"key":"value"}');
//$data = \Crossjoin\Json\json_decode('{"key":"value"}', false,);
//$data = \Crossjoin\Json\json_decode('{"key":"value"}', false, 512);
//$data = \Crossjoin\Json\json_decode('{"key":"value"}', false, 512, \JSON_BIGINT_AS_STRING);

// Also the functions json_last_error() and json_last_error_msg() can be used
if (\Crossjoin\Json\json_last_error() !== \JSON_ERROR_NONE) {
    $errorMessage = \Crossjoin\Json\json_last_error_msg();

    // Error handling
    // ...
} else {
    // Do something with the data
    // ...
}

扩展示例

前一个示例中的函数是为了方便替换原生函数而存在的。函数内部使用类 \Crossjoin\Json\Decoder,捕获所有异常(除了无效参数的异常)并返回与原生函数期望相同的结果。

如果您直接使用解码器类,可以定义如何处理字节顺序标记,并通过 json_last_error* 函数(尽管可以继续使用)来处理异常。

<?php
use Crossjoin\Json\Decoder;
use Crossjoin\Json\Exception\JsonException;
use Crossjoin\Json\Exception\NativeJsonErrorException;

// Get decoder instance with default options
$decoder = new Decoder();

// Get decoder instance that accepts input with byte order mark (which is the default)
//$decoder = new Decoder(true);

// Get decoder instance that does not accept input with byte order mark
//$decoder = new Decoder(false);

// Byte order mark support may also be enabled/disabled after initialization
//$decoder = new Decoder();
//$decoder->setIgnoreByteOrderMark(false);

// Decode the data
try {
    // Decode example (same arguments as the native PHP function).
    $data = $decoder->decode('{"key":"value"}', false, 512, \JSON_BIGINT_AS_STRING);
    
    // Do something with the data
    // ...
} catch (NativeJsonErrorException $e) {
    // Catch native JSON errors, wrapped in an exception. The exception's
    // message and code are the same as returned by the native json_last_error*
    // functions (which can still be used)
    
    // Get native JSON error code, for example \JSON_ERROR_SYNTAX,
    // same as returned by json_last_error()
    $jsonError = $e->getCode();
    
    // Get native JSON error message, same as returned by json_last_error_msg()
    $jsonErrorMessage = $e->getMessage();
    
    // Error handling
    // ...
} catch (JsonException $e) {
    // Catch misc errors, for example if JSON with an unsupported encoding was
    // used as input.

    // Error handling
    // ...
}

编码

它是如何工作的?

数据使用原生的 json_encode() 函数进行编码,因此结果 依赖于原生 PHP 函数(可能在不同的 PHP 版本之间有所不同)。

输入必须编码为 UTF-8(或兼容的 ASCII 编码)。输出编码默认为 UTF-8,但可以设置为不同的 Unicode 编码。编码转换在将数据编码为 JSON 之后应用。

注意:输出不包含字节顺序标记,因为 RFC 不允许这样做。它仅在解码 JSON 时允许接受。

基本示例

使用Crossjoin\Json命名空间中提供的函数的基本示例

<?php
// From PHP 5.6.0 you can also use namespaced functions to avoid the namespace
// prefixes below.
//use function \Crossjoin\Json\json_decode, \Crossjoin\Json\json_encode;
//use function \Crossjoin\Json\json_last_error, \Crossjoin\Json\json_last_error_msg;

// Encode example (same arguments as the native PHP function)
//
// Note: If an invalid type is used for one of the arguments, a
// \Crossjoin\Json\Exception\InvalidArgumentException exception is thrown,
// while the native PHP function may accept some of them.
$json = \Crossjoin\Json\json_encode(123);
//$json = \Crossjoin\Json\json_encode(123, \JSON_NUMERIC_CHECK);
//$json = \Crossjoin\Json\json_encode(123, \JSON_NUMERIC_CHECK, 512);

// Also the functions json_last_error() and json_last_error_msg() can be used
if (\Crossjoin\Json\json_last_error() !== \JSON_ERROR_NONE) {
    $errorMessage = \Crossjoin\Json\json_last_error_msg();

    // Error handling
    // ...
} else {
    // Do something with the JSON string
    // ...
}

扩展示例

前一个示例中的函数是为了方便替换原生函数而存在的。函数内部使用类 \Crossjoin\Json\Encoder,捕获所有异常(除了无效参数的异常)并返回与原生函数期望相同的结果。

如果您直接使用编码器类,可以定义输出编码,并通过 json_last_error* 函数(尽管可以继续使用)来处理异常。

<?php
use Crossjoin\Json\Encoder;
use Crossjoin\Json\Exception\JsonException;
use Crossjoin\Json\Exception\NativeJsonErrorException;

// Get encoder instance with default options
$encoder = new Encoder();

// Get encoder instance that uses UTF-8 encoding for the output (which is the default)
//$encoder = new Encoder(Encoder::UTF8);

// Get encoder instance that uses UTF-16BE encoding for the output
//$encoder = new Encoder(Encoder::UTF16BE);

// Get encoder instance that uses UTF-16LE encoding for the output
//$encoder = new Encoder(Encoder::UTF16LE);

// Get encoder instance that uses UTF-16BE encoding for the output
//$encoder = new Encoder(Encoder::UTF32BE);

// Get encoder instance that uses UTF-16LE encoding for the output
//$encoder = new Encoder(Encoder::UTF32LE);

// The encoding may also be changed after initialization
//$encoder = new Encoder();
//$encoder->setEncoding(Encoder::UTF16BE);

// Encode the data
try {
    // Encode example (same arguments as the native PHP function).
    $json = $encoder->encode('my data', \JSON_NUMERIC_CHECK, 512);
    
    // Do something with the JSON string
    // ...
} catch (NativeJsonErrorException $e) {
    // Catch native JSON errors, wrapped in an exception. The exception's
    // message and code are the same as returned by the native json_last_error*
    // functions (which can still be used)
    
    // Get native JSON error code, for example \JSON_ERROR_UNSUPPORTED_TYPE,
    // same as returned by json_last_error()
    $jsonError = $e->getCode();
    
    // Get native JSON error message, same as returned by json_last_error_msg()
    $jsonErrorMessage = $e->getMessage();
    
    // Error handling
    // ...
} catch (JsonException $e) {
    // Catch misc errors, for example if invalid data was used as input.

    // Error handling
    // ...
}

需要知道的事情

无效参数的处理

此库更严格地检查给定参数的类型。

例如,原生的 json_decode() 函数也接受整数或布尔值作为 JSON 字符串,这可能导致意外的结果。在这种情况下,此库将抛出 \Crossjoin\Json\Exception\InvalidArgumentException 异常。

后来 PHP 版本中添加的参数

原生 PHP 函数 json_decodejson_encode 的参数在不同版本之间有所不同。较老的 PHP 版本不支持所有参数。当使用替换函数 \Crossjoin\Json\json_decode\Crossjoin\Json\json_encode 时,这些参数可以设置,但只有在原生 PHP 版本支持它们时才会使用。

PHP < 5.5.0 中的错误消息

\Crossjoin\Json\json_last_error_msg() 函数返回原始错误消息,正如原生 PHP 函数 json_last_error_msg() 返回的消息一样——除了 PHP < 5.5.0,因为这些版本中不存在此函数。在这种情况下,将返回一个默认错误消息。

PHP < 5.5.0 的不同结果

在 PHP < 5.5.0 中尝试编码无效类型(例如资源)时,原生 PHP 函数 json_encode() 返回一个编码后的 null 值并触发错误。

该行为已调整为PHP 5.5.0的行为,因此此情况被视为错误,导致抛出 \Crossjoin\Json\Exception\InvalidArgumentException 异常。此错误不能用 json_last_error() 处理,因为在此之前PHP 5.5.0中不存在错误代码 \JSON_ERROR_UNSUPPORTED_TYPE。