{"id":15029991,"url":"https://github.com/xp-forge/json","last_synced_at":"2025-04-09T20:40:45.805Z","repository":{"id":20573332,"uuid":"23853755","full_name":"xp-forge/json","owner":"xp-forge","description":"JSON Reader and Writers for the XP Framework","archived":false,"fork":false,"pushed_at":"2024-08-05T20:01:55.000Z","size":275,"stargazers_count":3,"open_issues_count":1,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-23T22:37:01.678Z","etag":null,"topics":["json","parse","php7","php8","stream","xp-framework"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xp-forge.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-09-09T23:30:46.000Z","updated_at":"2024-01-17T15:49:24.000Z","dependencies_parsed_at":"2024-02-04T12:02:18.029Z","dependency_job_id":"3f61cf41-22fe-4414-8250-b57850f06f43","html_url":"https://github.com/xp-forge/json","commit_stats":null,"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xp-forge%2Fjson","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xp-forge%2Fjson/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xp-forge%2Fjson/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xp-forge%2Fjson/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xp-forge","download_url":"https://codeload.github.com/xp-forge/json/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248109626,"owners_count":21049347,"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":["json","parse","php7","php8","stream","xp-framework"],"created_at":"2024-09-24T20:12:10.395Z","updated_at":"2025-04-09T20:40:45.774Z","avatar_url":"https://github.com/xp-forge.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"JSON\n====\n\n[![Build status on GitHub](https://github.com/xp-forge/json/workflows/Tests/badge.svg)](https://github.com/xp-forge/json/actions)\n[![XP Framework Mdodule](https://raw.githubusercontent.com/xp-framework/web/master/static/xp-framework-badge.png)](https://github.com/xp-framework/core)\n[![BSD Licence](https://raw.githubusercontent.com/xp-framework/web/master/static/licence-bsd.png)](https://github.com/xp-framework/core/blob/master/LICENCE.md)\n[![Requires PHP 7.0+](https://raw.githubusercontent.com/xp-framework/web/master/static/php-7_0plus.svg)](http://php.net/)\n[![Supports PHP 8.0+](https://raw.githubusercontent.com/xp-framework/web/master/static/php-8_0plus.svg)](http://php.net/)\n[![Latest Stable Version](https://poser.pugx.org/xp-forge/json/version.png)](https://packagist.org/packages/xp-forge/json)\n\nReads and writes JSON to and from various input sources.\n\nExamples\n--------\nReading can be done from a string using one of the `Input` implementations:\n\n```php\n// Strings\n$value= Json::read('\"Test\"');\n\n// Input\n$in= new FileInput(new File('input.json'));\n$in= new StringInput('{\"Hello\": \"World\"}');\n$in= new StreamInput(new SocketInputStream(...));\n\n$value= Json::read($in);\n```\n\nWriting can be done to a string or using one of the `Output` implementations:\n\n```php\n// Strings\n$json= Json::of('Test');\n\n// Output\n$out= new FileOutput(new File('output.json'));\n$out= new StreamOutput(new SocketOuputStream(...));\n\nJson::write($value, $out);\n```\n\n### Formatted output\nTo change the output format, pass a `Format` instance to the output's constructor. The formats available are:\n\n* `DenseFormat($options)`: Best for network I/O, no unsignificant whitespace, default if nothing given and accessible via `Format::dense($options= ~Format::ESCAPE_SLASHES)`.\n* `WrappedFormat($indent, $options)`: Wraps first-level arrays and all objects, uses whitespace after commas colons. An instance of this format using 4 spaces for indentation and per default leaving forward slashes unescaped is available via `Format::wrapped($indent= \"    \", $options= ~Format::ESCAPE_SLASHES)`.\n\nThe available options that can be or'ed together are:\n\n* `Format::ESCAPE_SLASHES`: Escape forward-slashes with \"\\\" - default behavior.\n* `Format::ESCAPE_UNICODE`: Escape unicode with \"\\uXXXX\" - default behavior.\n* `Format::ESCAPE_ENTITIES`: Escape XML entities `\u0026`, `\"`, `\u003c` and `\u003e`. Per default, these are represented in their literal form.\n\n```php\n$out= new FileOutput(new File('glue.json'), Format::wrapped());\n$out-\u003ewrite([\n  'name'    =\u003e 'example/package',\n  'version' =\u003e '1.0.0',\n  'require' =\u003e [\n    'xp-forge/json'     =\u003e '^3.0',\n    'xp-framework/core' =\u003e '^10.0'\n  ]\n]);\n```\n\nThe above code will yield the following output:\n\n```json\n{\n    \"name\": \"example/package\",\n    \"version\": \"1.0.0'\",\n    \"require\": {\n        \"xp-forge/json\": \"^3.0\",\n        \"xp-framework/core\": \"^10.0\"\n    }\n}\n```\n\nSequential processing\n---------------------\nProcessing elements sequentially can save you memory and give a better performance in certain situations.\n\n### Reading\nYou can use the `elements()` method to receive an iterator over a JSON array. Instead of loading the entire source into memory and then returning the parsed array, it will parse one array element at a time, yielding them while going.\n\n```php\n$conn= new HttpConnection(...);\n$in= new StreamInput($conn-\u003eget('/search?q=example\u0026limit=1000')-\u003ein());\nforeach ($in-\u003eelements() as $element) {\n  // Process\n}\n```\n\nIf you get a huge object, you can also process it sequentially using the `pairs()` method. This will parse a single key/value pair at a time.\n\n```php\n$conn= new HttpConnection(...);\n$in= new StreamInput($conn-\u003eget('/resources/4711?expand=*')-\u003ein());\nforeach ($in-\u003epairs() as $key =\u003e $value) {\n  // Process\n}\n```\n\nTo detect the type of the data on the stream (again, without reading it completely), you can use the `type()` method.\n\n```php\n$conn= new HttpConnection(...);\n$in= new StreamInput($conn-\u003eget($resource)-\u003ein());\n$type= $in-\u003etype();\nif ($type-\u003eisArray()) {\n  // Handle arrays\n} else if ($type-\u003eisObject()) {\n  // Handle objects\n} else {\n  // Handle primitives\n}\n```\n\n### Writing\nTo write data sequentially, you can use the `begin()` method and the stream it returns. This makes sense when the source offers a way to read data sequentially, if you already have the entire data in memory, using `write()` has the same effect.\n\n```php\n$query= $conn-\u003equery('select * from person');\n\n$stream= (new StreamOutput(...))-\u003ebegin(Types::$ARRAY);\nwhile ($record= $query-\u003enext()) {\n  $stream-\u003eelement($record);\n}\n$stream-\u003eclose();\n```\n\nAs the `Stream` class implements the Closeable interface, it can be used in the `with` statement:\n\n```php\n$query= $conn-\u003equery('select * from person');\n\nwith ((new StreamOutput(...))-\u003ebegin(Types::$ARRAY), function($stream) use($query) {\n  while ($record= $query-\u003enext()) {\n    $stream-\u003eelement($record);\n  }\n});\n```\n\nFurther reading\n---------------\n* [Performance figures](https://github.com/xp-forge/json/wiki/Performance-overview). TL;DR: While slower than the native functionality, the performance overhead is in low millisecond ranges. Using sequential processing we have an advantage both performance- and memory-wise.\n* [Parsing JSON is a Minefield](http://seriot.ch/parsing_json.html). This library runs this test suite next to its own.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxp-forge%2Fjson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxp-forge%2Fjson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxp-forge%2Fjson/lists"}