{"id":13519612,"url":"https://github.com/webmozart/json","last_synced_at":"2025-04-09T04:05:25.197Z","repository":{"id":23439221,"uuid":"26802612","full_name":"webmozart/json","owner":"webmozart","description":"A robust JSON decoder/encoder with support for schema validation.","archived":false,"fork":false,"pushed_at":"2021-03-06T12:39:57.000Z","size":251,"stargazers_count":356,"open_issues_count":11,"forks_count":27,"subscribers_count":20,"default_branch":"master","last_synced_at":"2025-04-02T03:09:02.020Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/webmozart.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-11-18T09:53:29.000Z","updated_at":"2025-01-29T19:31:31.000Z","dependencies_parsed_at":"2022-08-05T22:16:02.384Z","dependency_job_id":null,"html_url":"https://github.com/webmozart/json","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webmozart%2Fjson","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webmozart%2Fjson/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webmozart%2Fjson/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webmozart%2Fjson/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/webmozart","download_url":"https://codeload.github.com/webmozart/json/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247974715,"owners_count":21026742,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T05:02:01.128Z","updated_at":"2025-04-09T04:05:25.164Z","avatar_url":"https://github.com/webmozart.png","language":"PHP","funding_links":[],"categories":["PHP","Libraries"],"sub_categories":[],"readme":"Webmozart JSON\n==============\n\n[![Build Status](https://travis-ci.org/webmozart/json.svg?branch=master)](https://travis-ci.org/webmozart/json)\n[![Build status](https://ci.appveyor.com/api/projects/status/icccqc0aq1molo96/branch/master?svg=true)](https://ci.appveyor.com/project/webmozart/json/branch/master)\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/webmozart/json/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/webmozart/json/?branch=master)\n[![Latest Stable Version](https://poser.pugx.org/webmozart/json/v/stable.svg)](https://packagist.org/packages/webmozart/json)\n[![Total Downloads](https://poser.pugx.org/webmozart/json/downloads.svg)](https://packagist.org/packages/webmozart/json)\n[![Dependency Status](https://www.versioneye.com/php/webmozart:json/1.2.2/badge.svg)](https://www.versioneye.com/php/webmozart:json/1.2.2)\n\nLatest release: [1.2.2](https://packagist.org/packages/webmozart/json#1.2.2)\n\nA robust wrapper for `json_encode()`/`json_decode()` that normalizes their\nbehavior across PHP versions, throws meaningful exceptions and supports schema\nvalidation by default.\n\nInstallation\n------------\n\nUse [Composer] to install the package:\n\n~~~\n$ composer require webmozart/json\n~~~\n\nEncoding\n--------\n\nUse the [`JsonEncoder`] to encode data as JSON:\n\n~~~php\nuse Webmozart\\Json\\JsonEncoder;\n\n$encoder = new JsonEncoder();\n\n// Store JSON in string\n$string = $encoder-\u003eencode($data);\n\n// Store JSON in file\n$encoder-\u003eencodeFile($data, '/path/to/file.json');\n~~~\n\nBy default, the [JSON schema] stored in the `$schema` property of the JSON\ndocument is used to validate the file. You can also pass the path to the schema \nin the last optional argument of both methods:\n\n~~~php\nuse Webmozart\\Json\\ValidationFailedException;\n\ntry {\n    $string = $encoder-\u003eencode($data, '/path/to/schema.json');\n} catch (ValidationFailedException $e) {\n    // data did not match schema \n}\n~~~\n\nDecoding\n--------\n\nUse the [`JsonDecoder`] to decode a JSON string/file:\n\n~~~php\nuse Webmozart\\Json\\JsonDecoder;\n\n$decoder = new JsonDecoder();\n\n// Read JSON string\n$data = $decoder-\u003edecode($string);\n\n// Read JSON file\n$data = $decoder-\u003edecodeFile('/path/to/file.json');\n~~~\n\nLike [`JsonEncoder`], the decoder accepts the path to a JSON schema in the last\noptional argument of its methods:\n\n~~~php\nuse Webmozart\\Json\\ValidationFailedException;\n\ntry {\n    $data = $decoder-\u003edecodeFile('/path/to/file.json', '/path/to/schema.json');\n} catch (ValidationFailedException $e) {\n    // data did not match schema \n}\n~~~\n\nValidation\n----------\n\nSometimes it is necessary to separate the steps of encoding/decoding JSON data\nand validating it against a schema. In this case, you can omit the schema\nargument during encoding/decoding and use the [`JsonValidator`] to validate the\ndata manually later on:\n\n~~~php\nuse Webmozart\\Json\\JsonDecoder;\nuse Webmozart\\Json\\JsonValidator;\nuse Webmozart\\Json\\ValidationFailedException;\n\n$decoder = new JsonDecoder();\n$validator = new JsonValidator();\n\n$data = $decoder-\u003edecodeFile('/path/to/file.json');\n\n// process $data...\n\n$errors = $validator-\u003evalidate($data, '/path/to/schema.json');\n\nif (count($errors) \u003e 0) {\n    // data did not match schema \n}\n~~~\n\nNote: This does not work if you use the `$schema` property to set the schema\n(see next section). If that property is set, the schema is always used for \nvalidation during encoding and decoding.\n\nSchemas\n-------\n\nYou are encouraged to store the schema of your JSON documents in the\n`$schema` property:\n\n~~~json\n{\n    \"$schema\": \"http://example.org/schemas/1.0/schema\"\n}\n~~~\n\nThe utilities in this package will load the schema from the URL and use it for\nvalidating the document. Obviously, this has a hit on performance and depends on\nthe availability of the server and an internet connection. Hence you are\nencouraged to ship the schema with your package. Use the [`LocalUriRetriever`]\nto map the URL to your local schema file:\n\n~~~php\n$uriRetriever = new UriRetriever();\n$uriRetriever-\u003esetUriRetriever(new LocalUriRetriever(\n    // base directory\n    __DIR__.'/../res/schemas',\n    // list of schema mappings\n    array(\n        'http://example.org/schemas/1.0/schema' =\u003e 'schema-1.0.json',\n    )\n));\n\n$validator = new JsonValidator(null, $uriRetriever);\n$encoder = new JsonEncoder($validator);\n$decoder = new JsonDecoder($validator);\n\n// ...\n~~~\n\nConversion\n----------\n\nYou can implement [`JsonConverter`] to encapsulate the conversion of objects\nfrom and to JSON structures in a single class:\n\n~~~php\nuse stdClass;\nuse Webmozart\\Json\\Conversion\\JsonConverter;\n\nclass ConfigFileJsonConverter implements JsonConverter\n{\n    const SCHEMA = 'http://example.org/schemas/1.0/schema';\n    \n    public function toJson($configFile, array $options = array())\n    {\n        $jsonData = new stdClass();\n        $jsonData-\u003e{'$schema'} = self::SCHEMA;\n         \n        if (null !== $configFile-\u003egetApplicationName()) {\n            $jsonData-\u003eapplication = $configFile-\u003egetApplicationName();\n        }\n        \n        // ...\n        \n        return $jsonData;\n    }\n    \n    public function fromJson($jsonData, array $options = array())\n    {\n        $configFile = new ConfigFile();\n        \n        if (isset($jsonData-\u003eapplication)) {\n            $configFile-\u003esetApplicationName($jsonData-\u003eapplication);\n        }\n        \n        // ...\n        \n        return $configFile;\n    }\n}\n~~~\n\nLoading and dumping `ConfigFile` objects is very simple now:\n\n~~~php\n$converter = new ConfigFileJsonConverter();\n\n// Load config.json as ConfigFile object\n$jsonData = $decoder-\u003edecodeFile('/path/to/config.json');\n$configFile = $converter-\u003efromJson($jsonData);\n\n// Save ConfigFile object as config.json\n$jsonData = $converter-\u003etoJson($configFile);\n$encoder-\u003eencodeFile($jsonData, '/path/to/config.json');\n~~~\n\nYou can automate the schema validation of your `ConfigFile` by wrapping the\nconverter in a `ValidatingConverter`:\n\n~~~php\nuse Webmozart\\Json\\Validation\\ValidatingConverter;\n\n$converter = new ValidatingConverter(new ConfigFileJsonConverter());\n~~~\n\nYou can also validate against an explicit schema by passing the schema to the\n`ValidatingConverter`:\n\n~~~php\nuse Webmozart\\Json\\Validation\\ValidatingConverter;\n\n$converter = new ValidatingConverter(\n    new ConfigFileJsonConverter(),\n    __DIR__.'/../res/schema/config-schema.json'\n);\n~~~\n\nVersioning and Migration\n------------------------\n\nWhen you continuously develop an application, you will enter the situation that\nyou need to change your JSON schemas. Updating JSON files to match their\nchanged schemas can be challenging and time consuming. This package supports a\nversioning mechanism to automate this migration.\n\nImagine `config.json` files in three different versions: 1.0, 2.0 and 3.0.\nThe name of a key changed between those versions:\n\nconfig.json (version 1.0)\n\n~~~json\n{\n    \"$schema\": \"http://example.org/schemas/1.0/schema\",\n    \"application\": \"Hello world!\"\n}\n~~~\n\nconfig.json (version 2.0)\n\n~~~json\n{\n    \"$schema\": \"http://example.org/schemas/2.0/schema\",\n    \"application.name\": \"Hello world!\"\n}\n~~~\n\nconfig.json (version 3.0)\n\n~~~json\n{\n    \"$schema\": \"http://example.org/schemas/3.0/schema\",\n    \"application\": {\n        \"name\": \"Hello world!\"\n    }\n}\n~~~\n\nYou can support files in any of these versions by implementing:\n\n1. A converter compatible with the latest version (e.g. 3.0)\n\n2. Migrations that migrate older versions to newer versions (e.g. 1.0  to\n   2.0 and 2.0 to 3.0.\n   \nLet's look at an example of a `ConfigFileJsonConverter` for version 3.0:\n\n~~~php\nuse stdClass;\nuse Webmozart\\Json\\Conversion\\JsonConverter;\n\nclass ConfigFileJsonConverter implements JsonConverter\n{\n    const SCHEMA = 'http://example.org/schemas/3.0/schema';\n    \n    public function toJson($configFile, array $options = array())\n    {\n        $jsonData = new stdClass();\n        $jsonData-\u003e{'$schema'} = self::SCHEMA;\n         \n        if (null !== $configFile-\u003egetApplicationName()) {\n            $jsonData-\u003eapplication = new stdClass();\n            $jsonData-\u003eapplication-\u003ename = $configFile-\u003egetApplicationName();\n        }\n        \n        // ...\n        \n        return $jsonData;\n    }\n    \n    public function fromJson($jsonData, array $options = array())\n    {\n        $configFile = new ConfigFile();\n        \n        if (isset($jsonData-\u003eapplication-\u003ename)) {\n            $configFile-\u003esetApplicationName($jsonData-\u003eapplication-\u003ename);\n        }\n        \n        // ...\n        \n        return $configFile;\n    }\n}\n~~~\n\nThis converter can be used as described in the previous section. However,\nit can only be used with `config.json` files in version 3.0.\n\nWe can add support for older files by implementing the [`JsonMigration`]\ninterface. This interface contains four methods:\n \n* `getSourceVersion()`: returns the source version of the migration\n* `getTargetVersion()`: returns the target version of the migration\n* `up(stdClass $jsonData)`: migrates from the source to the target version\n* `down(stdClass $jsonData)`: migrates from the target to the source version\n\n~~~php\nuse Webmozart\\Json\\Migration\\JsonMigration;\n\nclass ConfigFileJson20To30Migration implements JsonMigration\n{\n    const SOURCE_SCHEMA = 'http://example.org/schemas/2.0/schema';\n    \n    const TARGET_SCHEMA = 'http://example.org/schemas/3.0/schema';\n    \n    public function getSourceVersion()\n    {\n        return '2.0';\n    }\n    \n    public function getTargetVersion()\n    {\n        return '3.0';\n    }\n    \n    public function up(stdClass $jsonData)\n    {\n        $jsonData-\u003e{'$schema'} = self::TARGET_SCHEMA;\n        \n        if (isset($jsonData-\u003e{'application.name'})) {\n            $jsonData-\u003eapplication = new stdClass();\n            $jsonData-\u003eapplication-\u003ename = $jsonData-\u003e{'application.name'};\n            \n            unset($jsonData-\u003e{'application.name'});\n        )\n    }\n    \n    public function down(stdClass $jsonData)\n    {\n        $jsonData-\u003e{'$schema'} = self::SOURCE_SCHEMA;\n        \n        if (isset($jsonData-\u003eapplication-\u003ename)) {\n            $jsonData-\u003e{'application.name'} = $jsonData-\u003eapplication-\u003ename;\n            \n            unset($jsonData-\u003eapplication);\n        )\n    }\n}\n~~~\n\nWith a list of such migrations, we can create a `MigratingConverter` that\ndecorates our `ConfigFileJsonConverter`:\n\n~~~php\nuse Webmozart\\Json\\Migration\\MigratingConverter;\nuse Webmozart\\Json\\Migration\\MigrationManager;\n\n// Written for version 3.0\n$converter = new ConfigFileJsonConverter();\n\n// Support for older versions. The order of migrations does not matter.\n$migrationManager = new MigrationManager(array(\n    new ConfigFileJson10To20Migration(),\n    new ConfigFileJson20To30Migration(),\n));\n\n// Decorate the converter\n$converter = new MigratingConverter($converter, $migrationManager);\n~~~\n\nThe resulting converter is able to load and dump JSON files in any of the \nversions 1.0, 2.0 and 3.0.\n \n~~~php\n// Loads a file in version 1.0, 2.0 or 3.0\n$jsonData = $decoder-\u003edecodeFile('/path/to/config.json');\n$configFile = $converter-\u003efromJson($jsonData);\n\n// Writes the file in the latest version by default (3.0)\n$jsonData = $converter-\u003etoJson($configFile);\n$encoder-\u003eencodeFile($jsonData, '/path/to/config.json');\n\n// Writes the file in a specific version\n$jsonData = $converter-\u003etoJson($configFile, array(\n    'targetVersion' =\u003e '2.0',\n));\n$encoder-\u003eencodeFile($jsonData, '/path/to/config.json');\n~~~\n\n### Validation of Different Versions\n\nIf you want to add schema validation, wrap your encoder into a\n`ValidatingConverter`. You can wrap both the inner and the outer converter\nto make sure that both the JSON before and after running the migrations complies\nto the corresponding schemas.\n\n~~~php\n// Written for version 3.0\n$converter = new ConfigFileJsonConverter();\n\n// Decorate to validate against the schema at version 3.0\n$converter = new ValidatingConverter($converter);\n\n// Decorate to support different versions\n$converter = new MigratingConverter($converter, $migrationManager);\n\n// Decorate to validate against the old schema\n$converter = new ValidatingConverter($converter);\n~~~\n\nIf you store the version in a `version` field (see below) and want to use a\ncustom schema depending on that version, you can pass schema paths or closures\nfor resolving the schema paths:\n\n~~~php\n// Written for version 3.0\n$converter = new ConfigFileJsonConverter();\n\n// Decorate to validate against the schema at version 3.0\n$converter = new ValidatingConverter($converter, __DIR__.'/../res/schema/config-schema-3.0.json');\n\n// Decorate to support different versions\n$converter = new MigratingConverter($converter, $migrationManager);\n\n// Decorate to validate against the old schema\n$converter = new ValidatingConverter($converter, function ($jsonData) {\n    return __DIR__.'/../res/schema/config-schema-'.$jsonData-\u003eversion.'.json'\n});\n~~~\n\n### Using Custom Schema Versioning\n\nBy default, the version of the schema is stored in the schema name:\n\n~~~json\n{\n    \"$schema\": \"http://example.com/schemas/1.0/my-schema\"\n}\n~~~\n\nThe version must be enclosed by slashes. Appending the version to the schema, \nfor example, won't work:\n\n~~~json\n{\n    \"$schema\": \"http://example.com/schemas/my-schema-1.0\"\n}\n~~~\n\nYou can however customize the format of the schema URI by creating a \n`SchemaUriVersioner` with a custom regular expression:\n\n~~~php\nuse Webmozart\\Json\\Versioning\\SchemaUriVersioner;\n\n$versioner = new SchemaUriVersioner('~(?\u003c=-)\\d+\\.\\d+(?=$)~');\n\n$migrationManager = new MigrationManager(array(\n    // migrations...\n), $versioner);\n\n// ...\n~~~\n\nThe regular expression must match the version only. Make sure to wrap \ncharacters before and after the version in look-around assertions (`(?\u003c=...)`,\n`(?=...)`).\n\n### Storing the Version in a Field\n\nInstead of storing the version in the schema URI, you could also store it in\na separate field. For example, the field \"version\":\n\n~~~json\n{\n    \"version\": \"1.0\"\n}\n~~~\n\nThis use case is supported by the `VersionFieldVersioner` class:\n\n~~~php\nuse Webmozart\\Json\\Versioning\\VersionFieldVersioner;\n\n$versioner = new VersionFieldVersioner();\n\n$migrationManager = new MigrationManager(array(\n    // migrations...\n), $versioner);\n\n// ...\n~~~\n\nThe constructor of `VersionFieldVersioner` optionally accepts a custom field\nname used to store the version. The default field name is \"version\".\n\nAuthors\n-------\n\n* [Bernhard Schussek] a.k.a. [@webmozart]\n* [The Community Contributors]\n\nContribute\n----------\n\nContributions to the package are always welcome!\n\n* Report any bugs or issues you find on the [issue tracker].\n* You can grab the source code at the package's [Git repository].\n\nSupport\n-------\n\nIf you are having problems, send a mail to bschussek@gmail.com or shout out to\n[@webmozart] on Twitter.\n\nLicense\n-------\n\nAll contents of this package are licensed under the [MIT license].\n\n[Composer]: https://getcomposer.org\n[Bernhard Schussek]: http://webmozarts.com\n[The Community Contributors]: https://github.com/webmozart/json/graphs/contributors\n[issue tracker]: https://github.com/webmozart/json/issues\n[Git repository]: https://github.com/webmozart/json\n[@webmozart]: https://twitter.com/webmozart\n[MIT license]: LICENSE\n[JSON schema]: http://json-schema.org\n[`JsonEncoder`]: src/JsonEncoder.php\n[`JsonDecoder`]: src/JsonDecoder.php\n[`JsonValidator`]: src/JsonValidator.php\n[`JsonConverter`]: src/Conversion/JsonConverter.php\n[`JsonMigration`]: src/Migration/JsonMigration.php\n[`LocalUriRetriever`]: src/UriRetriever/LocalUriRetriever.php\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebmozart%2Fjson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwebmozart%2Fjson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebmozart%2Fjson/lists"}