此包已被弃用且不再维护。未建议替代包。

PHP 的 JSON 解码器和编码器,完全支持 Unicode,遵循 RFC 7159。除了 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 版本之间有所不同。较老的 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() 返回编码后的空值并触发错误。

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