jesseschalken/pure-json

带有错误检查和PHP与JSON值一对一映射的json_encode/json_decode包装器

1.3.0 2016-05-14 15:40 UTC

This package is not auto-updated.

Last update: 2024-09-14 18:27:13 UTC


README

json_encode()/json_decode()包装器,PHP 5.3+版本,JSON和PHP值之间实现一对一映射。

use PureJSON\JSON;

$json  = JSON::encode($value);
$value = JSON::decode($json);
  • JSON::encode()只接受可以通过JSON::decode()精确转换回原始值的值,因此JSON::decode(JSON::encode($x)) === $x。可接受的数据类型包括

    • int
    • string
    • float(但不能是INF-INFNAN
    • bool
    • null
    • array(其中元素也必须是有效的)
  • JSON::encode()/JSON::decode()默认将PHP字符串视为UTF-8。要编码/解码二进制或ISO-8859-1字符串,请使用JSON::encode(..., true)JSON::decode(..., true)

  • 要格式化输出JSON,请使用JSON::encode(..., ..., true)

  • JSON::encode()/JSON::decode()将检查json_last_error(),并抛出包含适当的代码消息PureJSON\JSONException

序列化

JSON::serialize()JSON::deserialize()方法与JSON::encode()JSON::decode()不同,它们将JSON的{...}语法映射到PHP对象和从PHP对象映射到PHP关联数组,而不是映射到PHP关联数组。与拒绝对象并接受关联数组的JSON::encode()相反,JSON::serialize()拒绝关联数组并接受对象。

为了使JSON::deserialize()能够重现JSON::serialize()提供的原始类的实例

  1. 提供给JSON::serialize()的对象必须实现PureJSON\Serializable接口。
  2. jsonProps()方法用于属性,而jsonType()用于填充特殊的@type属性以标识对象的类型。
  3. JSON::deserialize()需要显式列出实现PureJSON\Serializable接口的类,以便可能使用jsonCreate($props)方法实例化。

通过在JSON中存储类型标记而不是PHP类名,可以在不破坏现有序列化数据兼容性的情况下重命名PHP类,并且如果给JSON::deserialize()的JSON是由攻击者生成的,他们无法在显式列表之外实例化类。

示例

使用JSON::encode()/JSON::decode()

use PureJson\JSON;

$company = array(
    'name'      => 'Good Company',
    'employees' => array(
    	array(
        	'name' => 'Jesse',
            'role' => 'sales',
        ),
        array(
        	'name' => 'Ben',
            'role' => 'development',
        ),
    ),
);

// encode/decode will reproduce the original array
$json    = JSON::encode($company);
$company = JSON::decode($json);
{
    "name": "Good Company",
    "employees": [
        {
            "name": "Jesse",
            "role": "sales"
        },
        {
            "name": "Ben",
            "role": "Development"
        }
    ]
}

使用JSON::serialize()/JSON::deserialize()

use PureJson\JSON;
use PureJson\Serializable;

class Company implements Serializable {
    public static function jsonCreate(array $props) {
        return new self($props['name'], $props['employees']);
    }

    public static function jsonType() {
    	return 'company';
    }

    private $name;
    private $employees;

    public function __construct($name, $employees) {
    	$this->name      = $name;
        $this->employees = $employees;
    }

    public function jsonProps() {
        return array(
            'name'      => $this->name,
            'employees' => $this->employees,
        );
    }
}

class Employee implements Serializable {
    public static function jsonCreate(array $props) {
        return new self($props['name'], $props['role']);
    }

    public static function jsonType() {
        return 'employee';
    }

    private $name;
    private $role;

    public function __construct($name, $role) {
        $this->name = $name;
        $this->role = $role;
    }

    public function jsonProps() {
        return array(
            'name' => $this->name,
            'role' => $this->role,
        );
    }
}

$company = new Company(
    'Good Company',
    array(
    	new Employee('Jesse', 'sales'),
        new Employee('Ben', 'development'),
    )
);

// serialize/deserialize will produce the original object graph
$json    = JSON::serialize($company);
$company = JSON::deserialize($json, array(
    Company::class,
    Employee::class,
));
{
    "@type": "company",
    "name": "Good Company",
    "employees": [
        {
            "@type": "employee",
            "name": "Jesse",
            "role": "sales"
        },
        {
            "@type": "employee",
            "name": "Ben",
            "role": "Development"
        }
    ]
}