Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

A robust JSON decoder/encoder with support for schema validation.

License

NotificationsYou must be signed in to change notification settings

webmozart/json

Repository files navigation

Build StatusBuild statusScrutinizer Code QualityLatest Stable VersionTotal DownloadsDependency Status

Latest release:1.2.2

A robust wrapper forjson_encode()/json_decode() that normalizes theirbehavior across PHP versions, throws meaningful exceptions and supports schemavalidation by default.

Installation

UseComposer to install the package:

$ composer require webmozart/json

Encoding

Use theJsonEncoder to encode data as JSON:

useWebmozart\Json\JsonEncoder;$encoder =newJsonEncoder();// Store JSON in string$string =$encoder->encode($data);// Store JSON in file$encoder->encodeFile($data,'/path/to/file.json');

By default, theJSON schema stored in the$schema property of the JSONdocument is used to validate the file. You can also pass the path to the schemain the last optional argument of both methods:

useWebmozart\Json\ValidationFailedException;try {$string =$encoder->encode($data,'/path/to/schema.json');}catch (ValidationFailedException$e) {// data did not match schema}

Decoding

Use theJsonDecoder to decode a JSON string/file:

useWebmozart\Json\JsonDecoder;$decoder =newJsonDecoder();// Read JSON string$data =$decoder->decode($string);// Read JSON file$data =$decoder->decodeFile('/path/to/file.json');

LikeJsonEncoder, the decoder accepts the path to a JSON schema in the lastoptional argument of its methods:

useWebmozart\Json\ValidationFailedException;try {$data =$decoder->decodeFile('/path/to/file.json','/path/to/schema.json');}catch (ValidationFailedException$e) {// data did not match schema}

Validation

Sometimes it is necessary to separate the steps of encoding/decoding JSON dataand validating it against a schema. In this case, you can omit the schemaargument during encoding/decoding and use theJsonValidator to validate thedata manually later on:

useWebmozart\Json\JsonDecoder;useWebmozart\Json\JsonValidator;useWebmozart\Json\ValidationFailedException;$decoder =newJsonDecoder();$validator =newJsonValidator();$data =$decoder->decodeFile('/path/to/file.json');// process $data...$errors =$validator->validate($data,'/path/to/schema.json');if (count($errors) >0) {// data did not match schema}

Note: This does not work if you use the$schema property to set the schema(see next section). If that property is set, the schema is always used forvalidation during encoding and decoding.

Schemas

You are encouraged to store the schema of your JSON documents in the$schema property:

{"$schema":"http://example.org/schemas/1.0/schema"}

The utilities in this package will load the schema from the URL and use it forvalidating the document. Obviously, this has a hit on performance and depends onthe availability of the server and an internet connection. Hence you areencouraged to ship the schema with your package. Use theLocalUriRetrieverto map the URL to your local schema file:

$uriRetriever =newUriRetriever();$uriRetriever->setUriRetriever(newLocalUriRetriever(// base directory__DIR__.'/../res/schemas',// list of schema mappingsarray('http://example.org/schemas/1.0/schema' =>'schema-1.0.json',    )));$validator =newJsonValidator(null,$uriRetriever);$encoder =newJsonEncoder($validator);$decoder =newJsonDecoder($validator);// ...

Conversion

You can implementJsonConverter to encapsulate the conversion of objectsfrom and to JSON structures in a single class:

usestdClass;useWebmozart\Json\Conversion\JsonConverter;class ConfigFileJsonConverterimplements JsonConverter{constSCHEMA ='http://example.org/schemas/1.0/schema';publicfunctiontoJson($configFile,array$options =array())    {$jsonData =newstdClass();$jsonData->{'$schema'} =self::SCHEMA;if (null !==$configFile->getApplicationName()) {$jsonData->application =$configFile->getApplicationName();        }// ...return$jsonData;    }publicfunctionfromJson($jsonData,array$options =array())    {$configFile =newConfigFile();if (isset($jsonData->application)) {$configFile->setApplicationName($jsonData->application);        }// ...return$configFile;    }}

Loading and dumpingConfigFile objects is very simple now:

$converter =newConfigFileJsonConverter();// Load config.json as ConfigFile object$jsonData =$decoder->decodeFile('/path/to/config.json');$configFile =$converter->fromJson($jsonData);// Save ConfigFile object as config.json$jsonData =$converter->toJson($configFile);$encoder->encodeFile($jsonData,'/path/to/config.json');

You can automate the schema validation of yourConfigFile by wrapping theconverter in aValidatingConverter:

useWebmozart\Json\Validation\ValidatingConverter;$converter =newValidatingConverter(newConfigFileJsonConverter());

You can also validate against an explicit schema by passing the schema to theValidatingConverter:

useWebmozart\Json\Validation\ValidatingConverter;$converter =newValidatingConverter(newConfigFileJsonConverter(),__DIR__.'/../res/schema/config-schema.json');

Versioning and Migration

When you continuously develop an application, you will enter the situation thatyou need to change your JSON schemas. Updating JSON files to match theirchanged schemas can be challenging and time consuming. This package supports aversioning mechanism to automate this migration.

Imagineconfig.json files in three different versions: 1.0, 2.0 and 3.0.The name of a key changed between those versions:

config.json (version 1.0)

{"$schema":"http://example.org/schemas/1.0/schema","application":"Hello world!"}

config.json (version 2.0)

{"$schema":"http://example.org/schemas/2.0/schema","application.name":"Hello world!"}

config.json (version 3.0)

{"$schema":"http://example.org/schemas/3.0/schema","application": {"name":"Hello world!"    }}

You can support files in any of these versions by implementing:

  1. A converter compatible with the latest version (e.g. 3.0)

  2. Migrations that migrate older versions to newer versions (e.g. 1.0 to2.0 and 2.0 to 3.0.

Let's look at an example of aConfigFileJsonConverter for version 3.0:

usestdClass;useWebmozart\Json\Conversion\JsonConverter;class ConfigFileJsonConverterimplements JsonConverter{constSCHEMA ='http://example.org/schemas/3.0/schema';publicfunctiontoJson($configFile,array$options =array())    {$jsonData =newstdClass();$jsonData->{'$schema'} =self::SCHEMA;if (null !==$configFile->getApplicationName()) {$jsonData->application =newstdClass();$jsonData->application->name =$configFile->getApplicationName();        }// ...return$jsonData;    }publicfunctionfromJson($jsonData,array$options =array())    {$configFile =newConfigFile();if (isset($jsonData->application->name)) {$configFile->setApplicationName($jsonData->application->name);        }// ...return$configFile;    }}

This converter can be used as described in the previous section. However,it can only be used withconfig.json files in version 3.0.

We can add support for older files by implementing theJsonMigrationinterface. This interface contains four methods:

  • getSourceVersion(): returns the source version of the migration
  • getTargetVersion(): returns the target version of the migration
  • up(stdClass $jsonData): migrates from the source to the target version
  • down(stdClass $jsonData): migrates from the target to the source version
useWebmozart\Json\Migration\JsonMigration;class ConfigFileJson20To30Migrationimplements JsonMigration{constSOURCE_SCHEMA ='http://example.org/schemas/2.0/schema';constTARGET_SCHEMA ='http://example.org/schemas/3.0/schema';publicfunctiongetSourceVersion()    {return'2.0';    }publicfunctiongetTargetVersion()    {return'3.0';    }publicfunction up(stdClass$jsonData)    {$jsonData->{'$schema'} =self::TARGET_SCHEMA;if (isset($jsonData->{'application.name'})) {$jsonData->application =newstdClass();$jsonData->application->name =$jsonData->{'application.name'};                        unset($jsonData->{'application.name'});        )    }publicfunctiondown(stdClass$jsonData)    {$jsonData->{'$schema'} =self::SOURCE_SCHEMA;if (isset($jsonData->application->name)) {$jsonData->{'application.name'} =$jsonData->application->name;                        unset($jsonData->application);        )    }}

With a list of such migrations, we can create aMigratingConverter thatdecorates ourConfigFileJsonConverter:

useWebmozart\Json\Migration\MigratingConverter;useWebmozart\Json\Migration\MigrationManager;// Written for version 3.0$converter =newConfigFileJsonConverter();// Support for older versions. The order of migrations does not matter.$migrationManager =newMigrationManager(array(newConfigFileJson10To20Migration(),newConfigFileJson20To30Migration(),));// Decorate the converter$converter =newMigratingConverter($converter,$migrationManager);

The resulting converter is able to load and dump JSON files in any of theversions 1.0, 2.0 and 3.0.

// Loads a file in version 1.0, 2.0 or 3.0$jsonData =$decoder->decodeFile('/path/to/config.json');$configFile =$converter->fromJson($jsonData);// Writes the file in the latest version by default (3.0)$jsonData =$converter->toJson($configFile);$encoder->encodeFile($jsonData,'/path/to/config.json');// Writes the file in a specific version$jsonData =$converter->toJson($configFile,array('targetVersion' =>'2.0',));$encoder->encodeFile($jsonData,'/path/to/config.json');

Validation of Different Versions

If you want to add schema validation, wrap your encoder into aValidatingConverter. You can wrap both the inner and the outer converterto make sure that both the JSON before and after running the migrations compliesto the corresponding schemas.

// Written for version 3.0$converter =newConfigFileJsonConverter();// Decorate to validate against the schema at version 3.0$converter =newValidatingConverter($converter);// Decorate to support different versions$converter =newMigratingConverter($converter,$migrationManager);// Decorate to validate against the old schema$converter =newValidatingConverter($converter);

If you store the version in aversion field (see below) and want to use acustom schema depending on that version, you can pass schema paths or closuresfor resolving the schema paths:

// Written for version 3.0$converter =newConfigFileJsonConverter();// Decorate to validate against the schema at version 3.0$converter =newValidatingConverter($converter,__DIR__.'/../res/schema/config-schema-3.0.json');// Decorate to support different versions$converter =newMigratingConverter($converter,$migrationManager);// Decorate to validate against the old schema$converter =new ValidatingConverter($converter,function ($jsonData) {return__DIR__.'/../res/schema/config-schema-'.$jsonData->version.'.json'});

Using Custom Schema Versioning

By default, the version of the schema is stored in the schema name:

{"$schema":"http://example.com/schemas/1.0/my-schema"}

The version must be enclosed by slashes. Appending the version to the schema,for example, won't work:

{"$schema":"http://example.com/schemas/my-schema-1.0"}

You can however customize the format of the schema URI by creating aSchemaUriVersioner with a custom regular expression:

useWebmozart\Json\Versioning\SchemaUriVersioner;$versioner =newSchemaUriVersioner('~(?<=-)\d+\.\d+(?=$)~');$migrationManager =newMigrationManager(array(// migrations...),$versioner);// ...

The regular expression must match the version only. Make sure to wrapcharacters before and after the version in look-around assertions ((?<=...),(?=...)).

Storing the Version in a Field

Instead of storing the version in the schema URI, you could also store it ina separate field. For example, the field "version":

{"version":"1.0"}

This use case is supported by theVersionFieldVersioner class:

useWebmozart\Json\Versioning\VersionFieldVersioner;$versioner =newVersionFieldVersioner();$migrationManager =newMigrationManager(array(// migrations...),$versioner);// ...

The constructor ofVersionFieldVersioner optionally accepts a custom fieldname used to store the version. The default field name is "version".

Authors

Contribute

Contributions to the package are always welcome!

Support

If you are having problems, send a mail tobschussek@gmail.com or shout out to@webmozart on Twitter.

License

All contents of this package are licensed under theMIT license.

About

A robust JSON decoder/encoder with support for schema validation.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages


[8]ページ先頭

©2009-2025 Movatter.jp