Repository files navigation

WebFiori Json

A PHP library for creating and parsing JSON and JSONx strings. Supports all PHP scalar types, arrays, and objects with flexible property naming styles.

PHP 8.1+

Table of Contents

Key Features

  • Create well-formatted JSON strings from any PHP value (scalars, arrays, objects)
  • Decode JSON strings and files into Json objects
  • Typed deserialization via Json::decodeAs() with nested object hydration
  • Flexible property naming styles: camelCase, kebab-case, snake_case, or none
  • Letter case control: same, upper, lower
  • Custom object serialization via the JsonI interface
  • Auto-mapping of plain objects via public getter methods and public properties
  • Auto-detection of associative arrays as JSON objects
  • Attribute-based control: #[JsonProperty], #[JsonIgnore], #[JsonType]
  • Application-wide defaults via Json::setDefaults()
  • JSONx output (XML representation of JSON)
  • Save JSON output directly to a file

Supported PHP Versions

Build Status

Installation

composer require webfiori/jsonx

Quick Start

useWebFiori\Json\Json;
$json = newJson([
'name' => 'Ibrahim',
'age' => 30,
'married' => false,
'score' => 9.5,
'notes' => null,
]);
echo$json;

Output:

{"name":"Ibrahim","age":30,"married":false,"score":9.5,"notes":null}

You can also build the object incrementally:

$json = newJson();
$json->addString('name', 'Ibrahim');
$json->addNumber('age', 30);
$json->addBoolean('married', false);
$json->addNull('notes');

Usage

Working With Arrays

$json = newJson();
// Indexed array$json->addArray('tags', ['php', 'json', 'api']);
// Associative arrays are automatically encoded as JSON objects$json->addArray('address', ['city' => 'Riyadh', 'country' => 'SA']);
echo$json;

Output:

{"tags":["php","json","api"],"address":{"city":"Riyadh","country":"SA"}}

Working With Objects

Using JsonI Interface

Implement JsonI to fully control how an object is serialized:

useWebFiori\Json\Json;
useWebFiori\Json\JsonI;
class User implements JsonI {
publicfunction__construct(
privatestring$username,
privatestring$email
) {}
publicfunctiontoJSON(): Json {
returnnewJson(['username' => $this->username, 'email' => $this->email]);
}
}
$json = newJson();
$json->addObject('user', newUser('ibrahim', 'ibrahim@example.com'));
echo$json;

Output:

{"user":{"username":"ibrahim","email":"ibrahim@example.com"}}

Auto-Mapping Objects

Objects that don't implement JsonI are mapped automatically using:

  1. Public getter methods — any zero-parameter method prefixed with get is called. The property name is derived by stripping get (e.g. getName()Name with style none, or name with style camel).
  2. Public properties — extracted via reflection and added as-is.

Use #[JsonIgnore] to exclude specific getters or properties, and #[JsonProperty] to override the output name:

useWebFiori\Json\Json;
useWebFiori\Json\JsonIgnore;
useWebFiori\Json\JsonProperty;
class Product {
#[JsonProperty('product_sku')]
publicstring$sku = 'ABC-001';
#[JsonIgnore]
publicstring$internalCode = 'X-99';
privatestring$name;
privatefloat$price;
publicfunction__construct(string$name, float$price) {
$this->name = $name;
$this->price = $price;
}
publicfunctiongetName(): string { return$this->name; }
publicfunctiongetPrice(): float { return$this->price; }
#[JsonProperty('on_sale')]
publicfunctiongetAvailable(): bool { returntrue; }
#[JsonIgnore]
publicfunctiongetSecretMargin(): float { return0.42; }
}
$json = newJson([], 'snake');
$json->addObject('product', newProduct('Keyboard', 49.99));
echo$json;

Output:

{"product":{"name":"Keyboard","price":49.99,"on_sale":true,"product_sku":"ABC-001"}}

Property Naming Styles

Four naming styles are supported: none (default), camel, snake, kebab.
Three letter cases are supported: same (default), upper, lower.

$data = ['first-name' => 'Ibrahim', 'last-name' => 'Al-Shikh'];
echonewJson($data, 'none') . "\n"; // {"first-name":"Ibrahim","last-name":"Al-Shikh"}echonewJson($data, 'camel') . "\n"; // {"firstName":"Ibrahim","lastName":"Al-Shikh"}echonewJson($data, 'snake') . "\n"; // {"first_name":"Ibrahim","last_name":"Al-Shikh"}echonewJson($data, 'kebab') . "\n"; // {"first-name":"Ibrahim","last-name":"Al-Shikh"}

Set application-wide defaults:

Json::setDefaults(style: 'camel', case: 'lower', formatted: false);

Decoding JSON

Decode a JSON string:

$json = Json::decode('{"name":"Ibrahim","age":30}');
echo$json->get('name'); // Ibrahim

Read from a file:

$json = Json::fromJsonFile('/path/to/file.json');

Typed Deserialization

Deserialize JSON directly into typed objects:

class User {
publicfunction__construct(
privatestring$username,
privatestring$email
) {}
publicfunctiongetUsername(): string { return$this->username; }
publicfunctiongetEmail(): string { return$this->email; }
}
$user = Json::decodeAs('{"username":"ibrahim","email":"a@b.com"}', User::class);
echo$user->getUsername(); // ibrahim

Nested objects are resolved automatically via constructor type hints. Use #[JsonType] for arrays of objects:

useWebFiori\Json\JsonType;
class Order {
publicfunction__construct(
privateUser$customer,
#[JsonType(LineItem::class, isArray: true)]
privatearray$items
) {}
}
$order = Json::decodeAs($jsonString, Order::class);
$order->getCustomer(); // User instance$order->getItems(); // LineItem[] array

Runtime type mapping without attributes:

$json = Json::decode($jsonString);
$json->setTypeMap([
'customer' => User::class,
'items' => [LineItem::class],
]);
$json->get('customer'); // User instance$json->get('items'); // LineItem[] array

Saving to File

$json = newJson(['name' => 'Ibrahim', 'age' => 30]);
$json->toJsonFile('data', '/path/to/directory', true);
// Creates /path/to/directory/data.json

Converting to Array

The toArray() method converts a Json object to a plain PHP associative array without the overhead of encoding to a JSON string and decoding it back:

$json = newJson([
'name' => 'Ibrahim',
'age' => 30,
'active' => true,
]);
$address = newJson(['city' => 'Riyadh', 'country' => 'SA']);
$json->add('address', $address);
$array = $json->toArray();
// Result:// [// 'name' => 'Ibrahim',// 'age' => 30,// 'active' => true,// 'address' => [// 'city' => 'Riyadh',// 'country' => 'SA',// ],// ]

This is useful when passing structured data to functions expecting arrays, PHPUnit assertions, or merging with other arrays. See examples/11-to-array.php for more examples.

JSONx

JSONx is an IBM standard that represents JSON as XML:

$json = newJson(['name' => 'Ibrahim', 'age' => 30, 'isEmployed' => true]);
echo$json->toJSONxString();

Output:

<?xml version="1.0" encoding="UTF-8"?>
<json:objectxsi:schemaLocation="http://www.datapower.com/schemas/json jsonx.xsd"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
<json:stringname="name">Ibrahim</json:string>
<json:numbername="age">30</json:number>
<json:booleanname="isEmployed">true</json:boolean>
</json:object>

Error Handling

All errors throw \WebFiori\Json\JsonException:

try {
$json = Json::decode('{invalid json}');
} catch (\WebFiori\Json\JsonException$e) {
echo$e->getMessage();
}

API Reference

Classes

ClassDescription
JsonMain class for building, reading, and deserializing JSON data
JsonIInterface for custom object serialization
JsonConverterHandles serialization to JSON and JSONx strings
JsonDeserializerHandles typed deserialization of JSON into objects
PropertyRepresents a single JSON property
CaseConverterConverts property names between naming styles
JsonTypesConstants for JSON data types
JsonExceptionException thrown on JSON errors

Attributes

AttributeTargetDescription
#[JsonIgnore]Method, PropertyExclude from serialization
#[JsonProperty(name)]Method, PropertyOverride output name
#[JsonType(class, isArray)]Parameter, PropertySpecify type for deserialization

Key Methods — Json

MethodDescription
add(string $key, mixed $value, bool $arrayAsObj = false): boolAdd any value
addString(string $key, string $val): boolAdd a string
addNumber(string $key, int|float $value): boolAdd a number
addBoolean(string $key, bool $val = true): boolAdd a boolean
addNull(string $key): boolAdd a null value
addArray(string $key, array $value, bool $asObject = false): boolAdd an array
addObject(string $key, object &$val): boolAdd an object
get(string $key): mixedGet a property value
hasKey(string $key): boolCheck if a key exists
remove(string $key): ?PropertyRemove a property
setPropsStyle(string $style, string $lettersCase = 'same'): voidChange naming style
setIsFormatted(bool $bool): voidToggle formatted output
setTypeMap(array $map): voidSet type map for typed deserialization via get()
toJSONString(): stringGet JSON string
toJSONxString(): stringGet JSONx string
toArray(): arrayGet plain PHP associative array
toJsonFile(string $fileName, string $path, bool $override = false): voidSave to file
Json::decode(string $jsonStr): JsonDecode a JSON string
Json::decodeAs(string $jsonStr, string $className): objectDecode and hydrate a typed object
Json::fromJsonFile(string $path): JsonLoad from a JSON file
Json::setDefaults(?string $style, ?string $case, ?bool $formatted): voidSet application-wide defaults
Json::resetDefaults(): voidReset to library defaults

Testing

# Install dependencies
composer install
# Run tests
composer test

Contributing

Contributions are welcome! Please open an issue or submit a pull request on GitHub.

License

This library is licensed under the MIT License. See the LICENSE file for more details.

Support

If you encounter any issues, please open an issue on GitHub.

Changelog

See CHANGELOG.md for a list of changes.

About

A JSON helper classes for creating JSON strings in PHP.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

8 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

WebFiori Json

A PHP library for creating and parsing JSON and JSONx strings. Supports all PHP scalar types, arrays, and objects with flexible property naming styles.

PHP 8.1+

Table of Contents

Key Features

  • Create well-formatted JSON strings from any PHP value (scalars, arrays, objects)
  • Decode JSON strings and files into Json objects
  • Typed deserialization via Json::decodeAs() with nested object hydration
  • Flexible property naming styles: camelCase, kebab-case, snake_case, or none
  • Letter case control: same, upper, lower
  • Custom object serialization via the JsonI interface
  • Auto-mapping of plain objects via public getter methods and public properties
  • Auto-detection of associative arrays as JSON objects
  • Attribute-based control: #[JsonProperty], #[JsonIgnore], #[JsonType]
  • Application-wide defaults via Json::setDefaults()
  • JSONx output (XML representation of JSON)
  • Save JSON output directly to a file

Supported PHP Versions

Build Status

Installation

composer require webfiori/jsonx

Quick Start

useWebFiori\Json\Json;
$json = newJson([
'name' => 'Ibrahim',
'age' => 30,
'married' => false,
'score' => 9.5,
'notes' => null,
]);
echo$json;

Output:

{"name":"Ibrahim","age":30,"married":false,"score":9.5,"notes":null}

You can also build the object incrementally:

$json = newJson();
$json->addString('name', 'Ibrahim');
$json->addNumber('age', 30);
$json->addBoolean('married', false);
$json->addNull('notes');

Usage

Working With Arrays

$json = newJson();
// Indexed array$json->addArray('tags', ['php', 'json', 'api']);
// Associative arrays are automatically encoded as JSON objects$json->addArray('address', ['city' => 'Riyadh', 'country' => 'SA']);
echo$json;

Output:

{"tags":["php","json","api"],"address":{"city":"Riyadh","country":"SA"}}

Working With Objects

Using JsonI Interface

Implement JsonI to fully control how an object is serialized:

useWebFiori\Json\Json;
useWebFiori\Json\JsonI;
class User implements JsonI {
publicfunction__construct(
privatestring$username,
privatestring$email
) {}
publicfunctiontoJSON(): Json {
returnnewJson(['username' => $this->username, 'email' => $this->email]);
}
}
$json = newJson();
$json->addObject('user', newUser('ibrahim', 'ibrahim@example.com'));
echo$json;

Output:

{"user":{"username":"ibrahim","email":"ibrahim@example.com"}}

Auto-Mapping Objects

Objects that don't implement JsonI are mapped automatically using:

  1. Public getter methods — any zero-parameter method prefixed with get is called. The property name is derived by stripping get (e.g. getName()Name with style none, or name with style camel).
  2. Public properties — extracted via reflection and added as-is.

Use #[JsonIgnore] to exclude specific getters or properties, and #[JsonProperty] to override the output name:

useWebFiori\Json\Json;
useWebFiori\Json\JsonIgnore;
useWebFiori\Json\JsonProperty;
class Product {
#[JsonProperty('product_sku')]
publicstring$sku = 'ABC-001';
#[JsonIgnore]
publicstring$internalCode = 'X-99';
privatestring$name;
privatefloat$price;
publicfunction__construct(string$name, float$price) {
$this->name = $name;
$this->price = $price;
}
publicfunctiongetName(): string { return$this->name; }
publicfunctiongetPrice(): float { return$this->price; }
#[JsonProperty('on_sale')]
publicfunctiongetAvailable(): bool { returntrue; }
#[JsonIgnore]
publicfunctiongetSecretMargin(): float { return0.42; }
}
$json = newJson([], 'snake');
$json->addObject('product', newProduct('Keyboard', 49.99));
echo$json;

Output:

{"product":{"name":"Keyboard","price":49.99,"on_sale":true,"product_sku":"ABC-001"}}

Property Naming Styles

Four naming styles are supported: none (default), camel, snake, kebab.
Three letter cases are supported: same (default), upper, lower.

$data = ['first-name' => 'Ibrahim', 'last-name' => 'Al-Shikh'];
echonewJson($data, 'none') . "\n"; // {"first-name":"Ibrahim","last-name":"Al-Shikh"}echonewJson($data, 'camel') . "\n"; // {"firstName":"Ibrahim","lastName":"Al-Shikh"}echonewJson($data, 'snake') . "\n"; // {"first_name":"Ibrahim","last_name":"Al-Shikh"}echonewJson($data, 'kebab') . "\n"; // {"first-name":"Ibrahim","last-name":"Al-Shikh"}

Set application-wide defaults:

Json::setDefaults(style: 'camel', case: 'lower', formatted: false);

Decoding JSON

Decode a JSON string:

$json = Json::decode('{"name":"Ibrahim","age":30}');
echo$json->get('name'); // Ibrahim

Read from a file:

$json = Json::fromJsonFile('/path/to/file.json');

Typed Deserialization

Deserialize JSON directly into typed objects:

class User {
publicfunction__construct(
privatestring$username,
privatestring$email
) {}
publicfunctiongetUsername(): string { return$this->username; }
publicfunctiongetEmail(): string { return$this->email; }
}
$user = Json::decodeAs('{"username":"ibrahim","email":"a@b.com"}', User::class);
echo$user->getUsername(); // ibrahim

Nested objects are resolved automatically via constructor type hints. Use #[JsonType] for arrays of objects:

useWebFiori\Json\JsonType;
class Order {
publicfunction__construct(
privateUser$customer,
#[JsonType(LineItem::class, isArray: true)]
privatearray$items
) {}
}
$order = Json::decodeAs($jsonString, Order::class);
$order->getCustomer(); // User instance$order->getItems(); // LineItem[] array

Runtime type mapping without attributes:

$json = Json::decode($jsonString);
$json->setTypeMap([
'customer' => User::class,
'items' => [LineItem::class],
]);
$json->get('customer'); // User instance$json->get('items'); // LineItem[] array

Saving to File

$json = newJson(['name' => 'Ibrahim', 'age' => 30]);
$json->toJsonFile('data', '/path/to/directory', true);
// Creates /path/to/directory/data.json

Converting to Array

The toArray() method converts a Json object to a plain PHP associative array without the overhead of encoding to a JSON string and decoding it back:

$json = newJson([
'name' => 'Ibrahim',
'age' => 30,
'active' => true,
]);
$address = newJson(['city' => 'Riyadh', 'country' => 'SA']);
$json->add('address', $address);
$array = $json->toArray();
// Result:// [// 'name' => 'Ibrahim',// 'age' => 30,// 'active' => true,// 'address' => [// 'city' => 'Riyadh',// 'country' => 'SA',// ],// ]

This is useful when passing structured data to functions expecting arrays, PHPUnit assertions, or merging with other arrays. See examples/11-to-array.php for more examples.

JSONx

JSONx is an IBM standard that represents JSON as XML:

$json = newJson(['name' => 'Ibrahim', 'age' => 30, 'isEmployed' => true]);
echo$json->toJSONxString();

Output:

<?xml version="1.0" encoding="UTF-8"?>
<json:objectxsi:schemaLocation="http://www.datapower.com/schemas/json jsonx.xsd"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
<json:stringname="name">Ibrahim</json:string>
<json:numbername="age">30</json:number>
<json:booleanname="isEmployed">true</json:boolean>
</json:object>

Error Handling

All errors throw \WebFiori\Json\JsonException:

try {
$json = Json::decode('{invalid json}');
} catch (\WebFiori\Json\JsonException$e) {
echo$e->getMessage();
}

API Reference

Classes

ClassDescription
JsonMain class for building, reading, and deserializing JSON data
JsonIInterface for custom object serialization
JsonConverterHandles serialization to JSON and JSONx strings
JsonDeserializerHandles typed deserialization of JSON into objects
PropertyRepresents a single JSON property
CaseConverterConverts property names between naming styles
JsonTypesConstants for JSON data types
JsonExceptionException thrown on JSON errors

Attributes

AttributeTargetDescription
#[JsonIgnore]Method, PropertyExclude from serialization
#[JsonProperty(name)]Method, PropertyOverride output name
#[JsonType(class, isArray)]Parameter, PropertySpecify type for deserialization

Key Methods — Json

MethodDescription
add(string $key, mixed $value, bool $arrayAsObj = false): boolAdd any value
addString(string $key, string $val): boolAdd a string
addNumber(string $key, int|float $value): boolAdd a number
addBoolean(string $key, bool $val = true): boolAdd a boolean
addNull(string $key): boolAdd a null value
addArray(string $key, array $value, bool $asObject = false): boolAdd an array
addObject(string $key, object &$val): boolAdd an object
get(string $key): mixedGet a property value
hasKey(string $key): boolCheck if a key exists
remove(string $key): ?PropertyRemove a property
setPropsStyle(string $style, string $lettersCase = 'same'): voidChange naming style
setIsFormatted(bool $bool): voidToggle formatted output
setTypeMap(array $map): voidSet type map for typed deserialization via get()
toJSONString(): stringGet JSON string
toJSONxString(): stringGet JSONx string
toArray(): arrayGet plain PHP associative array
toJsonFile(string $fileName, string $path, bool $override = false): voidSave to file
Json::decode(string $jsonStr): JsonDecode a JSON string
Json::decodeAs(string $jsonStr, string $className): objectDecode and hydrate a typed object
Json::fromJsonFile(string $path): JsonLoad from a JSON file
Json::setDefaults(?string $style, ?string $case, ?bool $formatted): voidSet application-wide defaults
Json::resetDefaults(): voidReset to library defaults

Testing

# Install dependencies
composer install
# Run tests
composer test

Contributing

Contributions are welcome! Please open an issue or submit a pull request on GitHub.

License

This library is licensed under the MIT License. See the LICENSE file for more details.

Support

If you encounter any issues, please open an issue on GitHub.

Changelog

See CHANGELOG.md for a list of changes.

About

A JSON helper classes for creating JSON strings in PHP.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

8 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

WebFiori Json

A PHP library for creating and parsing JSON and JSONx strings. Supports all PHP scalar types, arrays, and objects with flexible property naming styles.

PHP 8.1+

Table of Contents

Key Features

  • Create well-formatted JSON strings from any PHP value (scalars, arrays, objects)
  • Decode JSON strings and files into Json objects
  • Typed deserialization via Json::decodeAs() with nested object hydration
  • Flexible property naming styles: camelCase, kebab-case, snake_case, or none
  • Letter case control: same, upper, lower
  • Custom object serialization via the JsonI interface
  • Auto-mapping of plain objects via public getter methods and public properties
  • Auto-detection of associative arrays as JSON objects
  • Attribute-based control: #[JsonProperty], #[JsonIgnore], #[JsonType]
  • Application-wide defaults via Json::setDefaults()
  • JSONx output (XML representation of JSON)
  • Save JSON output directly to a file

Supported PHP Versions

Build Status

Installation

composer require webfiori/jsonx

Quick Start

useWebFiori\Json\Json;
$json = newJson([
'name' => 'Ibrahim',
'age' => 30,
'married' => false,
'score' => 9.5,
'notes' => null,
]);
echo$json;

Output:

{"name":"Ibrahim","age":30,"married":false,"score":9.5,"notes":null}

You can also build the object incrementally:

$json = newJson();
$json->addString('name', 'Ibrahim');
$json->addNumber('age', 30);
$json->addBoolean('married', false);
$json->addNull('notes');

Usage

Working With Arrays

$json = newJson();
// Indexed array$json->addArray('tags', ['php', 'json', 'api']);
// Associative arrays are automatically encoded as JSON objects$json->addArray('address', ['city' => 'Riyadh', 'country' => 'SA']);
echo$json;

Output:

{"tags":["php","json","api"],"address":{"city":"Riyadh","country":"SA"}}

Working With Objects

Using JsonI Interface

Implement JsonI to fully control how an object is serialized:

useWebFiori\Json\Json;
useWebFiori\Json\JsonI;
class User implements JsonI {
publicfunction__construct(
privatestring$username,
privatestring$email
) {}
publicfunctiontoJSON(): Json {
returnnewJson(['username' => $this->username, 'email' => $this->email]);
}
}
$json = newJson();
$json->addObject('user', newUser('ibrahim', 'ibrahim@example.com'));
echo$json;

Output:

{"user":{"username":"ibrahim","email":"ibrahim@example.com"}}

Auto-Mapping Objects

Objects that don't implement JsonI are mapped automatically using:

  1. Public getter methods — any zero-parameter method prefixed with get is called. The property name is derived by stripping get (e.g. getName()Name with style none, or name with style camel).
  2. Public properties — extracted via reflection and added as-is.

Use #[JsonIgnore] to exclude specific getters or properties, and #[JsonProperty] to override the output name:

useWebFiori\Json\Json;
useWebFiori\Json\JsonIgnore;
useWebFiori\Json\JsonProperty;
class Product {
#[JsonProperty('product_sku')]
publicstring$sku = 'ABC-001';
#[JsonIgnore]
publicstring$internalCode = 'X-99';
privatestring$name;
privatefloat$price;
publicfunction__construct(string$name, float$price) {
$this->name = $name;
$this->price = $price;
}
publicfunctiongetName(): string { return$this->name; }
publicfunctiongetPrice(): float { return$this->price; }
#[JsonProperty('on_sale')]
publicfunctiongetAvailable(): bool { returntrue; }
#[JsonIgnore]
publicfunctiongetSecretMargin(): float { return0.42; }
}
$json = newJson([], 'snake');
$json->addObject('product', newProduct('Keyboard', 49.99));
echo$json;

Output:

{"product":{"name":"Keyboard","price":49.99,"on_sale":true,"product_sku":"ABC-001"}}

Property Naming Styles

Four naming styles are supported: none (default), camel, snake, kebab.
Three letter cases are supported: same (default), upper, lower.

$data = ['first-name' => 'Ibrahim', 'last-name' => 'Al-Shikh'];
echonewJson($data, 'none') . "\n"; // {"first-name":"Ibrahim","last-name":"Al-Shikh"}echonewJson($data, 'camel') . "\n"; // {"firstName":"Ibrahim","lastName":"Al-Shikh"}echonewJson($data, 'snake') . "\n"; // {"first_name":"Ibrahim","last_name":"Al-Shikh"}echonewJson($data, 'kebab') . "\n"; // {"first-name":"Ibrahim","last-name":"Al-Shikh"}

Set application-wide defaults:

Json::setDefaults(style: 'camel', case: 'lower', formatted: false);

Decoding JSON

Decode a JSON string:

$json = Json::decode('{"name":"Ibrahim","age":30}');
echo$json->get('name'); // Ibrahim

Read from a file:

$json = Json::fromJsonFile('/path/to/file.json');

Typed Deserialization

Deserialize JSON directly into typed objects:

class User {
publicfunction__construct(
privatestring$username,
privatestring$email
) {}
publicfunctiongetUsername(): string { return$this->username; }
publicfunctiongetEmail(): string { return$this->email; }
}
$user = Json::decodeAs('{"username":"ibrahim","email":"a@b.com"}', User::class);
echo$user->getUsername(); // ibrahim

Nested objects are resolved automatically via constructor type hints. Use #[JsonType] for arrays of objects:

useWebFiori\Json\JsonType;
class Order {
publicfunction__construct(
privateUser$customer,
#[JsonType(LineItem::class, isArray: true)]
privatearray$items
) {}
}
$order = Json::decodeAs($jsonString, Order::class);
$order->getCustomer(); // User instance$order->getItems(); // LineItem[] array

Runtime type mapping without attributes:

$json = Json::decode($jsonString);
$json->setTypeMap([
'customer' => User::class,
'items' => [LineItem::class],
]);
$json->get('customer'); // User instance$json->get('items'); // LineItem[] array

Saving to File

$json = newJson(['name' => 'Ibrahim', 'age' => 30]);
$json->toJsonFile('data', '/path/to/directory', true);
// Creates /path/to/directory/data.json

Converting to Array

The toArray() method converts a Json object to a plain PHP associative array without the overhead of encoding to a JSON string and decoding it back:

$json = newJson([
'name' => 'Ibrahim',
'age' => 30,
'active' => true,
]);
$address = newJson(['city' => 'Riyadh', 'country' => 'SA']);
$json->add('address', $address);
$array = $json->toArray();
// Result:// [// 'name' => 'Ibrahim',// 'age' => 30,// 'active' => true,// 'address' => [// 'city' => 'Riyadh',// 'country' => 'SA',// ],// ]

This is useful when passing structured data to functions expecting arrays, PHPUnit assertions, or merging with other arrays. See examples/11-to-array.php for more examples.

JSONx

JSONx is an IBM standard that represents JSON as XML:

$json = newJson(['name' => 'Ibrahim', 'age' => 30, 'isEmployed' => true]);
echo$json->toJSONxString();

Output:

<?xml version="1.0" encoding="UTF-8"?>
<json:objectxsi:schemaLocation="http://www.datapower.com/schemas/json jsonx.xsd"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
<json:stringname="name">Ibrahim</json:string>
<json:numbername="age">30</json:number>
<json:booleanname="isEmployed">true</json:boolean>
</json:object>

Error Handling

All errors throw \WebFiori\Json\JsonException:

try {
$json = Json::decode('{invalid json}');
} catch (\WebFiori\Json\JsonException$e) {
echo$e->getMessage();
}

API Reference

Classes

ClassDescription
JsonMain class for building, reading, and deserializing JSON data
JsonIInterface for custom object serialization
JsonConverterHandles serialization to JSON and JSONx strings
JsonDeserializerHandles typed deserialization of JSON into objects
PropertyRepresents a single JSON property
CaseConverterConverts property names between naming styles
JsonTypesConstants for JSON data types
JsonExceptionException thrown on JSON errors

Attributes

AttributeTargetDescription
#[JsonIgnore]Method, PropertyExclude from serialization
#[JsonProperty(name)]Method, PropertyOverride output name
#[JsonType(class, isArray)]Parameter, PropertySpecify type for deserialization

Key Methods — Json

MethodDescription
add(string $key, mixed $value, bool $arrayAsObj = false): boolAdd any value
addString(string $key, string $val): boolAdd a string
addNumber(string $key, int|float $value): boolAdd a number
addBoolean(string $key, bool $val = true): boolAdd a boolean
addNull(string $key): boolAdd a null value
addArray(string $key, array $value, bool $asObject = false): boolAdd an array
addObject(string $key, object &$val): boolAdd an object
get(string $key): mixedGet a property value
hasKey(string $key): boolCheck if a key exists
remove(string $key): ?PropertyRemove a property
setPropsStyle(string $style, string $lettersCase = 'same'): voidChange naming style
setIsFormatted(bool $bool): voidToggle formatted output
setTypeMap(array $map): voidSet type map for typed deserialization via get()
toJSONString(): stringGet JSON string
toJSONxString(): stringGet JSONx string
toArray(): arrayGet plain PHP associative array
toJsonFile(string $fileName, string $path, bool $override = false): voidSave to file
Json::decode(string $jsonStr): JsonDecode a JSON string
Json::decodeAs(string $jsonStr, string $className): objectDecode and hydrate a typed object
Json::fromJsonFile(string $path): JsonLoad from a JSON file
Json::setDefaults(?string $style, ?string $case, ?bool $formatted): voidSet application-wide defaults
Json::resetDefaults(): voidReset to library defaults

Testing

# Install dependencies
composer install
# Run tests
composer test

Contributing

Contributions are welcome! Please open an issue or submit a pull request on GitHub.

License

This library is licensed under the MIT License. See the LICENSE file for more details.

Support

If you encounter any issues, please open an issue on GitHub.

Changelog

See CHANGELOG.md for a list of changes.

About

A JSON helper classes for creating JSON strings in PHP.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

8 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

WebFiori Json

A PHP library for creating and parsing JSON and JSONx strings. Supports all PHP scalar types, arrays, and objects with flexible property naming styles.

PHP 8.1+

Table of Contents

Key Features

  • Create well-formatted JSON strings from any PHP value (scalars, arrays, objects)
  • Decode JSON strings and files into Json objects
  • Typed deserialization via Json::decodeAs() with nested object hydration
  • Flexible property naming styles: camelCase, kebab-case, snake_case, or none
  • Letter case control: same, upper, lower
  • Custom object serialization via the JsonI interface
  • Auto-mapping of plain objects via public getter methods and public properties
  • Auto-detection of associative arrays as JSON objects
  • Attribute-based control: #[JsonProperty], #[JsonIgnore], #[JsonType]
  • Application-wide defaults via Json::setDefaults()
  • JSONx output (XML representation of JSON)
  • Save JSON output directly to a file

Supported PHP Versions

Build Status

Installation

composer require webfiori/jsonx

Quick Start

useWebFiori\Json\Json;
$json = newJson([
'name' => 'Ibrahim',
'age' => 30,
'married' => false,
'score' => 9.5,
'notes' => null,
]);
echo$json;

Output:

{"name":"Ibrahim","age":30,"married":false,"score":9.5,"notes":null}

You can also build the object incrementally:

$json = newJson();
$json->addString('name', 'Ibrahim');
$json->addNumber('age', 30);
$json->addBoolean('married', false);
$json->addNull('notes');

Usage

Working With Arrays

$json = newJson();
// Indexed array$json->addArray('tags', ['php', 'json', 'api']);
// Associative arrays are automatically encoded as JSON objects$json->addArray('address', ['city' => 'Riyadh', 'country' => 'SA']);
echo$json;

Output:

{"tags":["php","json","api"],"address":{"city":"Riyadh","country":"SA"}}

Working With Objects

Using JsonI Interface

Implement JsonI to fully control how an object is serialized:

useWebFiori\Json\Json;
useWebFiori\Json\JsonI;
class User implements JsonI {
publicfunction__construct(
privatestring$username,
privatestring$email
) {}
publicfunctiontoJSON(): Json {
returnnewJson(['username' => $this->username, 'email' => $this->email]);
}
}
$json = newJson();
$json->addObject('user', newUser('ibrahim', 'ibrahim@example.com'));
echo$json;

Output:

{"user":{"username":"ibrahim","email":"ibrahim@example.com"}}

Auto-Mapping Objects

Objects that don't implement JsonI are mapped automatically using:

  1. Public getter methods — any zero-parameter method prefixed with get is called. The property name is derived by stripping get (e.g. getName()Name with style none, or name with style camel).
  2. Public properties — extracted via reflection and added as-is.

Use #[JsonIgnore] to exclude specific getters or properties, and #[JsonProperty] to override the output name:

useWebFiori\Json\Json;
useWebFiori\Json\JsonIgnore;
useWebFiori\Json\JsonProperty;
class Product {
#[JsonProperty('product_sku')]
publicstring$sku = 'ABC-001';
#[JsonIgnore]
publicstring$internalCode = 'X-99';
privatestring$name;
privatefloat$price;
publicfunction__construct(string$name, float$price) {
$this->name = $name;
$this->price = $price;
}
publicfunctiongetName(): string { return$this->name; }
publicfunctiongetPrice(): float { return$this->price; }
#[JsonProperty('on_sale')]
publicfunctiongetAvailable(): bool { returntrue; }
#[JsonIgnore]
publicfunctiongetSecretMargin(): float { return0.42; }
}
$json = newJson([], 'snake');
$json->addObject('product', newProduct('Keyboard', 49.99));
echo$json;

Output:

{"product":{"name":"Keyboard","price":49.99,"on_sale":true,"product_sku":"ABC-001"}}

Property Naming Styles

Four naming styles are supported: none (default), camel, snake, kebab.
Three letter cases are supported: same (default), upper, lower.

$data = ['first-name' => 'Ibrahim', 'last-name' => 'Al-Shikh'];
echonewJson($data, 'none') . "\n"; // {"first-name":"Ibrahim","last-name":"Al-Shikh"}echonewJson($data, 'camel') . "\n"; // {"firstName":"Ibrahim","lastName":"Al-Shikh"}echonewJson($data, 'snake') . "\n"; // {"first_name":"Ibrahim","last_name":"Al-Shikh"}echonewJson($data, 'kebab') . "\n"; // {"first-name":"Ibrahim","last-name":"Al-Shikh"}

Set application-wide defaults:

Json::setDefaults(style: 'camel', case: 'lower', formatted: false);

Decoding JSON

Decode a JSON string:

$json = Json::decode('{"name":"Ibrahim","age":30}');
echo$json->get('name'); // Ibrahim

Read from a file:

$json = Json::fromJsonFile('/path/to/file.json');

Typed Deserialization

Deserialize JSON directly into typed objects:

class User {
publicfunction__construct(
privatestring$username,
privatestring$email
) {}
publicfunctiongetUsername(): string { return$this->username; }
publicfunctiongetEmail(): string { return$this->email; }
}
$user = Json::decodeAs('{"username":"ibrahim","email":"a@b.com"}', User::class);
echo$user->getUsername(); // ibrahim

Nested objects are resolved automatically via constructor type hints. Use #[JsonType] for arrays of objects:

useWebFiori\Json\JsonType;
class Order {
publicfunction__construct(
privateUser$customer,
#[JsonType(LineItem::class, isArray: true)]
privatearray$items
) {}
}
$order = Json::decodeAs($jsonString, Order::class);
$order->getCustomer(); // User instance$order->getItems(); // LineItem[] array

Runtime type mapping without attributes:

$json = Json::decode($jsonString);
$json->setTypeMap([
'customer' => User::class,
'items' => [LineItem::class],
]);
$json->get('customer'); // User instance$json->get('items'); // LineItem[] array

Saving to File

$json = newJson(['name' => 'Ibrahim', 'age' => 30]);
$json->toJsonFile('data', '/path/to/directory', true);
// Creates /path/to/directory/data.json

Converting to Array

The toArray() method converts a Json object to a plain PHP associative array without the overhead of encoding to a JSON string and decoding it back:

$json = newJson([
'name' => 'Ibrahim',
'age' => 30,
'active' => true,
]);
$address = newJson(['city' => 'Riyadh', 'country' => 'SA']);
$json->add('address', $address);
$array = $json->toArray();
// Result:// [// 'name' => 'Ibrahim',// 'age' => 30,// 'active' => true,// 'address' => [// 'city' => 'Riyadh',// 'country' => 'SA',// ],// ]

This is useful when passing structured data to functions expecting arrays, PHPUnit assertions, or merging with other arrays. See examples/11-to-array.php for more examples.

JSONx

JSONx is an IBM standard that represents JSON as XML:

$json = newJson(['name' => 'Ibrahim', 'age' => 30, 'isEmployed' => true]);
echo$json->toJSONxString();

Output:

<?xml version="1.0" encoding="UTF-8"?>
<json:objectxsi:schemaLocation="http://www.datapower.com/schemas/json jsonx.xsd"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
<json:stringname="name">Ibrahim</json:string>
<json:numbername="age">30</json:number>
<json:booleanname="isEmployed">true</json:boolean>
</json:object>

Error Handling

All errors throw \WebFiori\Json\JsonException:

try {
$json = Json::decode('{invalid json}');
} catch (\WebFiori\Json\JsonException$e) {
echo$e->getMessage();
}

API Reference

Classes

ClassDescription
JsonMain class for building, reading, and deserializing JSON data
JsonIInterface for custom object serialization
JsonConverterHandles serialization to JSON and JSONx strings
JsonDeserializerHandles typed deserialization of JSON into objects
PropertyRepresents a single JSON property
CaseConverterConverts property names between naming styles
JsonTypesConstants for JSON data types
JsonExceptionException thrown on JSON errors

Attributes

AttributeTargetDescription
#[JsonIgnore]Method, PropertyExclude from serialization
#[JsonProperty(name)]Method, PropertyOverride output name
#[JsonType(class, isArray)]Parameter, PropertySpecify type for deserialization

Key Methods — Json

MethodDescription
add(string $key, mixed $value, bool $arrayAsObj = false): boolAdd any value
addString(string $key, string $val): boolAdd a string
addNumber(string $key, int|float $value): boolAdd a number
addBoolean(string $key, bool $val = true): boolAdd a boolean
addNull(string $key): boolAdd a null value
addArray(string $key, array $value, bool $asObject = false): boolAdd an array
addObject(string $key, object &$val): boolAdd an object
get(string $key): mixedGet a property value
hasKey(string $key): boolCheck if a key exists
remove(string $key): ?PropertyRemove a property
setPropsStyle(string $style, string $lettersCase = 'same'): voidChange naming style
setIsFormatted(bool $bool): voidToggle formatted output
setTypeMap(array $map): voidSet type map for typed deserialization via get()
toJSONString(): stringGet JSON string
toJSONxString(): stringGet JSONx string
toArray(): arrayGet plain PHP associative array
toJsonFile(string $fileName, string $path, bool $override = false): voidSave to file
Json::decode(string $jsonStr): JsonDecode a JSON string
Json::decodeAs(string $jsonStr, string $className): objectDecode and hydrate a typed object
Json::fromJsonFile(string $path): JsonLoad from a JSON file
Json::setDefaults(?string $style, ?string $case, ?bool $formatted): voidSet application-wide defaults
Json::resetDefaults(): voidReset to library defaults

Testing

# Install dependencies
composer install
# Run tests
composer test

Contributing

Contributions are welcome! Please open an issue or submit a pull request on GitHub.

License

This library is licensed under the MIT License. See the LICENSE file for more details.

Support

If you encounter any issues, please open an issue on GitHub.

Changelog

See CHANGELOG.md for a list of changes.

About

A JSON helper classes for creating JSON strings in PHP.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

8 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

WebFiori Json

A PHP library for creating and parsing JSON and JSONx strings. Supports all PHP scalar types, arrays, and objects with flexible property naming styles.

PHP 8.1+

Table of Contents

Key Features

  • Create well-formatted JSON strings from any PHP value (scalars, arrays, objects)
  • Decode JSON strings and files into Json objects
  • Typed deserialization via Json::decodeAs() with nested object hydration
  • Flexible property naming styles: camelCase, kebab-case, snake_case, or none
  • Letter case control: same, upper, lower
  • Custom object serialization via the JsonI interface
  • Auto-mapping of plain objects via public getter methods and public properties
  • Auto-detection of associative arrays as JSON objects
  • Attribute-based control: #[JsonProperty], #[JsonIgnore], #[JsonType]
  • Application-wide defaults via Json::setDefaults()
  • JSONx output (XML representation of JSON)
  • Save JSON output directly to a file

Supported PHP Versions

Build Status

Installation

composer require webfiori/jsonx

Quick Start

useWebFiori\Json\Json;
$json = newJson([
'name' => 'Ibrahim',
'age' => 30,
'married' => false,
'score' => 9.5,
'notes' => null,
]);
echo$json;

Output:

{"name":"Ibrahim","age":30,"married":false,"score":9.5,"notes":null}

You can also build the object incrementally:

$json = newJson();
$json->addString('name', 'Ibrahim');
$json->addNumber('age', 30);
$json->addBoolean('married', false);
$json->addNull('notes');

Usage

Working With Arrays

$json = newJson();
// Indexed array$json->addArray('tags', ['php', 'json', 'api']);
// Associative arrays are automatically encoded as JSON objects$json->addArray('address', ['city' => 'Riyadh', 'country' => 'SA']);
echo$json;

Output:

{"tags":["php","json","api"],"address":{"city":"Riyadh","country":"SA"}}

Working With Objects

Using JsonI Interface

Implement JsonI to fully control how an object is serialized:

useWebFiori\Json\Json;
useWebFiori\Json\JsonI;
class User implements JsonI {
publicfunction__construct(
privatestring$username,
privatestring$email
) {}
publicfunctiontoJSON(): Json {
returnnewJson(['username' => $this->username, 'email' => $this->email]);
}
}
$json = newJson();
$json->addObject('user', newUser('ibrahim', 'ibrahim@example.com'));
echo$json;

Output:

{"user":{"username":"ibrahim","email":"ibrahim@example.com"}}

Auto-Mapping Objects

Objects that don't implement JsonI are mapped automatically using:

  1. Public getter methods — any zero-parameter method prefixed with get is called. The property name is derived by stripping get (e.g. getName()Name with style none, or name with style camel).
  2. Public properties — extracted via reflection and added as-is.

Use #[JsonIgnore] to exclude specific getters or properties, and #[JsonProperty] to override the output name:

useWebFiori\Json\Json;
useWebFiori\Json\JsonIgnore;
useWebFiori\Json\JsonProperty;
class Product {
#[JsonProperty('product_sku')]
publicstring$sku = 'ABC-001';
#[JsonIgnore]
publicstring$internalCode = 'X-99';
privatestring$name;
privatefloat$price;
publicfunction__construct(string$name, float$price) {
$this->name = $name;
$this->price = $price;
}
publicfunctiongetName(): string { return$this->name; }
publicfunctiongetPrice(): float { return$this->price; }
#[JsonProperty('on_sale')]
publicfunctiongetAvailable(): bool { returntrue; }
#[JsonIgnore]
publicfunctiongetSecretMargin(): float { return0.42; }
}
$json = newJson([], 'snake');
$json->addObject('product', newProduct('Keyboard', 49.99));
echo$json;

Output:

{"product":{"name":"Keyboard","price":49.99,"on_sale":true,"product_sku":"ABC-001"}}

Property Naming Styles

Four naming styles are supported: none (default), camel, snake, kebab.
Three letter cases are supported: same (default), upper, lower.

$data = ['first-name' => 'Ibrahim', 'last-name' => 'Al-Shikh'];
echonewJson($data, 'none') . "\n"; // {"first-name":"Ibrahim","last-name":"Al-Shikh"}echonewJson($data, 'camel') . "\n"; // {"firstName":"Ibrahim","lastName":"Al-Shikh"}echonewJson($data, 'snake') . "\n"; // {"first_name":"Ibrahim","last_name":"Al-Shikh"}echonewJson($data, 'kebab') . "\n"; // {"first-name":"Ibrahim","last-name":"Al-Shikh"}

Set application-wide defaults:

Json::setDefaults(style: 'camel', case: 'lower', formatted: false);

Decoding JSON

Decode a JSON string:

$json = Json::decode('{"name":"Ibrahim","age":30}');
echo$json->get('name'); // Ibrahim

Read from a file:

$json = Json::fromJsonFile('/path/to/file.json');

Typed Deserialization

Deserialize JSON directly into typed objects:

class User {
publicfunction__construct(
privatestring$username,
privatestring$email
) {}
publicfunctiongetUsername(): string { return$this->username; }
publicfunctiongetEmail(): string { return$this->email; }
}
$user = Json::decodeAs('{"username":"ibrahim","email":"a@b.com"}', User::class);
echo$user->getUsername(); // ibrahim

Nested objects are resolved automatically via constructor type hints. Use #[JsonType] for arrays of objects:

useWebFiori\Json\JsonType;
class Order {
publicfunction__construct(
privateUser$customer,
#[JsonType(LineItem::class, isArray: true)]
privatearray$items
) {}
}
$order = Json::decodeAs($jsonString, Order::class);
$order->getCustomer(); // User instance$order->getItems(); // LineItem[] array

Runtime type mapping without attributes:

$json = Json::decode($jsonString);
$json->setTypeMap([
'customer' => User::class,
'items' => [LineItem::class],
]);
$json->get('customer'); // User instance$json->get('items'); // LineItem[] array

Saving to File

$json = newJson(['name' => 'Ibrahim', 'age' => 30]);
$json->toJsonFile('data', '/path/to/directory', true);
// Creates /path/to/directory/data.json

Converting to Array

The toArray() method converts a Json object to a plain PHP associative array without the overhead of encoding to a JSON string and decoding it back:

$json = newJson([
'name' => 'Ibrahim',
'age' => 30,
'active' => true,
]);
$address = newJson(['city' => 'Riyadh', 'country' => 'SA']);
$json->add('address', $address);
$array = $json->toArray();
// Result:// [// 'name' => 'Ibrahim',// 'age' => 30,// 'active' => true,// 'address' => [// 'city' => 'Riyadh',// 'country' => 'SA',// ],// ]

This is useful when passing structured data to functions expecting arrays, PHPUnit assertions, or merging with other arrays. See examples/11-to-array.php for more examples.

JSONx

JSONx is an IBM standard that represents JSON as XML:

$json = newJson(['name' => 'Ibrahim', 'age' => 30, 'isEmployed' => true]);
echo$json->toJSONxString();

Output:

<?xml version="1.0" encoding="UTF-8"?>
<json:objectxsi:schemaLocation="http://www.datapower.com/schemas/json jsonx.xsd"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
<json:stringname="name">Ibrahim</json:string>
<json:numbername="age">30</json:number>
<json:booleanname="isEmployed">true</json:boolean>
</json:object>

Error Handling

All errors throw \WebFiori\Json\JsonException:

try {
$json = Json::decode('{invalid json}');
} catch (\WebFiori\Json\JsonException$e) {
echo$e->getMessage();
}

API Reference

Classes

ClassDescription
JsonMain class for building, reading, and deserializing JSON data
JsonIInterface for custom object serialization
JsonConverterHandles serialization to JSON and JSONx strings
JsonDeserializerHandles typed deserialization of JSON into objects
PropertyRepresents a single JSON property
CaseConverterConverts property names between naming styles
JsonTypesConstants for JSON data types
JsonExceptionException thrown on JSON errors

Attributes

AttributeTargetDescription
#[JsonIgnore]Method, PropertyExclude from serialization
#[JsonProperty(name)]Method, PropertyOverride output name
#[JsonType(class, isArray)]Parameter, PropertySpecify type for deserialization

Key Methods — Json

MethodDescription
add(string $key, mixed $value, bool $arrayAsObj = false): boolAdd any value
addString(string $key, string $val): boolAdd a string
addNumber(string $key, int|float $value): boolAdd a number
addBoolean(string $key, bool $val = true): boolAdd a boolean
addNull(string $key): boolAdd a null value
addArray(string $key, array $value, bool $asObject = false): boolAdd an array
addObject(string $key, object &$val): boolAdd an object
get(string $key): mixedGet a property value
hasKey(string $key): boolCheck if a key exists
remove(string $key): ?PropertyRemove a property
setPropsStyle(string $style, string $lettersCase = 'same'): voidChange naming style
setIsFormatted(bool $bool): voidToggle formatted output
setTypeMap(array $map): voidSet type map for typed deserialization via get()
toJSONString(): stringGet JSON string
toJSONxString(): stringGet JSONx string
toArray(): arrayGet plain PHP associative array
toJsonFile(string $fileName, string $path, bool $override = false): voidSave to file
Json::decode(string $jsonStr): JsonDecode a JSON string
Json::decodeAs(string $jsonStr, string $className): objectDecode and hydrate a typed object
Json::fromJsonFile(string $path): JsonLoad from a JSON file
Json::setDefaults(?string $style, ?string $case, ?bool $formatted): voidSet application-wide defaults
Json::resetDefaults(): voidReset to library defaults

Testing

# Install dependencies
composer install
# Run tests
composer test

Contributing

Contributions are welcome! Please open an issue or submit a pull request on GitHub.

License

This library is licensed under the MIT License. See the LICENSE file for more details.

Support

If you encounter any issues, please open an issue on GitHub.

Changelog

See CHANGELOG.md for a list of changes.

About

A JSON helper classes for creating JSON strings in PHP.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

8 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

WebFiori Json

A PHP library for creating and parsing JSON and JSONx strings. Supports all PHP scalar types, arrays, and objects with flexible property naming styles.

PHP 8.1+

Table of Contents

Key Features

  • Create well-formatted JSON strings from any PHP value (scalars, arrays, objects)
  • Decode JSON strings and files into Json objects
  • Typed deserialization via Json::decodeAs() with nested object hydration
  • Flexible property naming styles: camelCase, kebab-case, snake_case, or none
  • Letter case control: same, upper, lower
  • Custom object serialization via the JsonI interface
  • Auto-mapping of plain objects via public getter methods and public properties
  • Auto-detection of associative arrays as JSON objects
  • Attribute-based control: #[JsonProperty], #[JsonIgnore], #[JsonType]
  • Application-wide defaults via Json::setDefaults()
  • JSONx output (XML representation of JSON)
  • Save JSON output directly to a file

Supported PHP Versions

Build Status

Installation

composer require webfiori/jsonx

Quick Start

useWebFiori\Json\Json;
$json = newJson([
'name' => 'Ibrahim',
'age' => 30,
'married' => false,
'score' => 9.5,
'notes' => null,
]);
echo$json;

Output:

{"name":"Ibrahim","age":30,"married":false,"score":9.5,"notes":null}

You can also build the object incrementally:

$json = newJson();
$json->addString('name', 'Ibrahim');
$json->addNumber('age', 30);
$json->addBoolean('married', false);
$json->addNull('notes');

Usage

Working With Arrays

$json = newJson();
// Indexed array$json->addArray('tags', ['php', 'json', 'api']);
// Associative arrays are automatically encoded as JSON objects$json->addArray('address', ['city' => 'Riyadh', 'country' => 'SA']);
echo$json;

Output:

{"tags":["php","json","api"],"address":{"city":"Riyadh","country":"SA"}}

Working With Objects

Using JsonI Interface

Implement JsonI to fully control how an object is serialized:

useWebFiori\Json\Json;
useWebFiori\Json\JsonI;
class User implements JsonI {
publicfunction__construct(
privatestring$username,
privatestring$email
) {}
publicfunctiontoJSON(): Json {
returnnewJson(['username' => $this->username, 'email' => $this->email]);
}
}
$json = newJson();
$json->addObject('user', newUser('ibrahim', 'ibrahim@example.com'));
echo$json;

Output:

{"user":{"username":"ibrahim","email":"ibrahim@example.com"}}

Auto-Mapping Objects

Objects that don't implement JsonI are mapped automatically using:

  1. Public getter methods — any zero-parameter method prefixed with get is called. The property name is derived by stripping get (e.g. getName()Name with style none, or name with style camel).
  2. Public properties — extracted via reflection and added as-is.

Use #[JsonIgnore] to exclude specific getters or properties, and #[JsonProperty] to override the output name:

useWebFiori\Json\Json;
useWebFiori\Json\JsonIgnore;
useWebFiori\Json\JsonProperty;
class Product {
#[JsonProperty('product_sku')]
publicstring$sku = 'ABC-001';
#[JsonIgnore]
publicstring$internalCode = 'X-99';
privatestring$name;
privatefloat$price;
publicfunction__construct(string$name, float$price) {
$this->name = $name;
$this->price = $price;
}
publicfunctiongetName(): string { return$this->name; }
publicfunctiongetPrice(): float { return$this->price; }
#[JsonProperty('on_sale')]
publicfunctiongetAvailable(): bool { returntrue; }
#[JsonIgnore]
publicfunctiongetSecretMargin(): float { return0.42; }
}
$json = newJson([], 'snake');
$json->addObject('product', newProduct('Keyboard', 49.99));
echo$json;

Output:

{"product":{"name":"Keyboard","price":49.99,"on_sale":true,"product_sku":"ABC-001"}}

Property Naming Styles

Four naming styles are supported: none (default), camel, snake, kebab.
Three letter cases are supported: same (default), upper, lower.

$data = ['first-name' => 'Ibrahim', 'last-name' => 'Al-Shikh'];
echonewJson($data, 'none') . "\n"; // {"first-name":"Ibrahim","last-name":"Al-Shikh"}echonewJson($data, 'camel') . "\n"; // {"firstName":"Ibrahim","lastName":"Al-Shikh"}echonewJson($data, 'snake') . "\n"; // {"first_name":"Ibrahim","last_name":"Al-Shikh"}echonewJson($data, 'kebab') . "\n"; // {"first-name":"Ibrahim","last-name":"Al-Shikh"}

Set application-wide defaults:

Json::setDefaults(style: 'camel', case: 'lower', formatted: false);

Decoding JSON

Decode a JSON string:

$json = Json::decode('{"name":"Ibrahim","age":30}');
echo$json->get('name'); // Ibrahim

Read from a file:

$json = Json::fromJsonFile('/path/to/file.json');

Typed Deserialization

Deserialize JSON directly into typed objects:

class User {
publicfunction__construct(
privatestring$username,
privatestring$email
) {}
publicfunctiongetUsername(): string { return$this->username; }
publicfunctiongetEmail(): string { return$this->email; }
}
$user = Json::decodeAs('{"username":"ibrahim","email":"a@b.com"}', User::class);
echo$user->getUsername(); // ibrahim

Nested objects are resolved automatically via constructor type hints. Use #[JsonType] for arrays of objects:

useWebFiori\Json\JsonType;
class Order {
publicfunction__construct(
privateUser$customer,
#[JsonType(LineItem::class, isArray: true)]
privatearray$items
) {}
}
$order = Json::decodeAs($jsonString, Order::class);
$order->getCustomer(); // User instance$order->getItems(); // LineItem[] array

Runtime type mapping without attributes:

$json = Json::decode($jsonString);
$json->setTypeMap([
'customer' => User::class,
'items' => [LineItem::class],
]);
$json->get('customer'); // User instance$json->get('items'); // LineItem[] array

Saving to File

$json = newJson(['name' => 'Ibrahim', 'age' => 30]);
$json->toJsonFile('data', '/path/to/directory', true);
// Creates /path/to/directory/data.json

Converting to Array

The toArray() method converts a Json object to a plain PHP associative array without the overhead of encoding to a JSON string and decoding it back:

$json = newJson([
'name' => 'Ibrahim',
'age' => 30,
'active' => true,
]);
$address = newJson(['city' => 'Riyadh', 'country' => 'SA']);
$json->add('address', $address);
$array = $json->toArray();
// Result:// [// 'name' => 'Ibrahim',// 'age' => 30,// 'active' => true,// 'address' => [// 'city' => 'Riyadh',// 'country' => 'SA',// ],// ]

This is useful when passing structured data to functions expecting arrays, PHPUnit assertions, or merging with other arrays. See examples/11-to-array.php for more examples.

JSONx

JSONx is an IBM standard that represents JSON as XML:

$json = newJson(['name' => 'Ibrahim', 'age' => 30, 'isEmployed' => true]);
echo$json->toJSONxString();

Output:

<?xml version="1.0" encoding="UTF-8"?>
<json:objectxsi:schemaLocation="http://www.datapower.com/schemas/json jsonx.xsd"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
<json:stringname="name">Ibrahim</json:string>
<json:numbername="age">30</json:number>
<json:booleanname="isEmployed">true</json:boolean>
</json:object>

Error Handling

All errors throw \WebFiori\Json\JsonException:

try {
$json = Json::decode('{invalid json}');
} catch (\WebFiori\Json\JsonException$e) {
echo$e->getMessage();
}

API Reference

Classes

ClassDescription
JsonMain class for building, reading, and deserializing JSON data
JsonIInterface for custom object serialization
JsonConverterHandles serialization to JSON and JSONx strings
JsonDeserializerHandles typed deserialization of JSON into objects
PropertyRepresents a single JSON property
CaseConverterConverts property names between naming styles
JsonTypesConstants for JSON data types
JsonExceptionException thrown on JSON errors

Attributes

AttributeTargetDescription
#[JsonIgnore]Method, PropertyExclude from serialization
#[JsonProperty(name)]Method, PropertyOverride output name
#[JsonType(class, isArray)]Parameter, PropertySpecify type for deserialization

Key Methods — Json

MethodDescription
add(string $key, mixed $value, bool $arrayAsObj = false): boolAdd any value
addString(string $key, string $val): boolAdd a string
addNumber(string $key, int|float $value): boolAdd a number
addBoolean(string $key, bool $val = true): boolAdd a boolean
addNull(string $key): boolAdd a null value
addArray(string $key, array $value, bool $asObject = false): boolAdd an array
addObject(string $key, object &$val): boolAdd an object
get(string $key): mixedGet a property value
hasKey(string $key): boolCheck if a key exists
remove(string $key): ?PropertyRemove a property
setPropsStyle(string $style, string $lettersCase = 'same'): voidChange naming style
setIsFormatted(bool $bool): voidToggle formatted output
setTypeMap(array $map): voidSet type map for typed deserialization via get()
toJSONString(): stringGet JSON string
toJSONxString(): stringGet JSONx string
toArray(): arrayGet plain PHP associative array
toJsonFile(string $fileName, string $path, bool $override = false): voidSave to file
Json::decode(string $jsonStr): JsonDecode a JSON string
Json::decodeAs(string $jsonStr, string $className): objectDecode and hydrate a typed object
Json::fromJsonFile(string $path): JsonLoad from a JSON file
Json::setDefaults(?string $style, ?string $case, ?bool $formatted): voidSet application-wide defaults
Json::resetDefaults(): voidReset to library defaults

Testing

# Install dependencies
composer install
# Run tests
composer test

Contributing

Contributions are welcome! Please open an issue or submit a pull request on GitHub.

License

This library is licensed under the MIT License. See the LICENSE file for more details.

Support

If you encounter any issues, please open an issue on GitHub.

Changelog

See CHANGELOG.md for a list of changes.

About

A JSON helper classes for creating JSON strings in PHP.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

8 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

WebFiori Json

A PHP library for creating and parsing JSON and JSONx strings. Supports all PHP scalar types, arrays, and objects with flexible property naming styles.

PHP 8.1+

Table of Contents

Key Features

  • Create well-formatted JSON strings from any PHP value (scalars, arrays, objects)
  • Decode JSON strings and files into Json objects
  • Typed deserialization via Json::decodeAs() with nested object hydration
  • Flexible property naming styles: camelCase, kebab-case, snake_case, or none
  • Letter case control: same, upper, lower
  • Custom object serialization via the JsonI interface
  • Auto-mapping of plain objects via public getter methods and public properties
  • Auto-detection of associative arrays as JSON objects
  • Attribute-based control: #[JsonProperty], #[JsonIgnore], #[JsonType]
  • Application-wide defaults via Json::setDefaults()
  • JSONx output (XML representation of JSON)
  • Save JSON output directly to a file

Supported PHP Versions

Build Status

Installation

composer require webfiori/jsonx

Quick Start

useWebFiori\Json\Json;
$json = newJson([
'name' => 'Ibrahim',
'age' => 30,
'married' => false,
'score' => 9.5,
'notes' => null,
]);
echo$json;

Output:

{"name":"Ibrahim","age":30,"married":false,"score":9.5,"notes":null}

You can also build the object incrementally:

$json = newJson();
$json->addString('name', 'Ibrahim');
$json->addNumber('age', 30);
$json->addBoolean('married', false);
$json->addNull('notes');

Usage

Working With Arrays

$json = newJson();
// Indexed array$json->addArray('tags', ['php', 'json', 'api']);
// Associative arrays are automatically encoded as JSON objects$json->addArray('address', ['city' => 'Riyadh', 'country' => 'SA']);
echo$json;

Output:

{"tags":["php","json","api"],"address":{"city":"Riyadh","country":"SA"}}

Working With Objects

Using JsonI Interface

Implement JsonI to fully control how an object is serialized:

useWebFiori\Json\Json;
useWebFiori\Json\JsonI;
class User implements JsonI {
publicfunction__construct(
privatestring$username,
privatestring$email
) {}
publicfunctiontoJSON(): Json {
returnnewJson(['username' => $this->username, 'email' => $this->email]);
}
}
$json = newJson();
$json->addObject('user', newUser('ibrahim', 'ibrahim@example.com'));
echo$json;

Output:

{"user":{"username":"ibrahim","email":"ibrahim@example.com"}}

Auto-Mapping Objects

Objects that don't implement JsonI are mapped automatically using:

  1. Public getter methods — any zero-parameter method prefixed with get is called. The property name is derived by stripping get (e.g. getName()Name with style none, or name with style camel).
  2. Public properties — extracted via reflection and added as-is.

Use #[JsonIgnore] to exclude specific getters or properties, and #[JsonProperty] to override the output name:

useWebFiori\Json\Json;
useWebFiori\Json\JsonIgnore;
useWebFiori\Json\JsonProperty;
class Product {
#[JsonProperty('product_sku')]
publicstring$sku = 'ABC-001';
#[JsonIgnore]
publicstring$internalCode = 'X-99';
privatestring$name;
privatefloat$price;
publicfunction__construct(string$name, float$price) {
$this->name = $name;
$this->price = $price;
}
publicfunctiongetName(): string { return$this->name; }
publicfunctiongetPrice(): float { return$this->price; }
#[JsonProperty('on_sale')]
publicfunctiongetAvailable(): bool { returntrue; }
#[JsonIgnore]
publicfunctiongetSecretMargin(): float { return0.42; }
}
$json = newJson([], 'snake');
$json->addObject('product', newProduct('Keyboard', 49.99));
echo$json;

Output:

{"product":{"name":"Keyboard","price":49.99,"on_sale":true,"product_sku":"ABC-001"}}

Property Naming Styles

Four naming styles are supported: none (default), camel, snake, kebab.
Three letter cases are supported: same (default), upper, lower.

$data = ['first-name' => 'Ibrahim', 'last-name' => 'Al-Shikh'];
echonewJson($data, 'none') . "\n"; // {"first-name":"Ibrahim","last-name":"Al-Shikh"}echonewJson($data, 'camel') . "\n"; // {"firstName":"Ibrahim","lastName":"Al-Shikh"}echonewJson($data, 'snake') . "\n"; // {"first_name":"Ibrahim","last_name":"Al-Shikh"}echonewJson($data, 'kebab') . "\n"; // {"first-name":"Ibrahim","last-name":"Al-Shikh"}

Set application-wide defaults:

Json::setDefaults(style: 'camel', case: 'lower', formatted: false);

Decoding JSON

Decode a JSON string:

$json = Json::decode('{"name":"Ibrahim","age":30}');
echo$json->get('name'); // Ibrahim

Read from a file:

$json = Json::fromJsonFile('/path/to/file.json');

Typed Deserialization

Deserialize JSON directly into typed objects:

class User {
publicfunction__construct(
privatestring$username,
privatestring$email
) {}
publicfunctiongetUsername(): string { return$this->username; }
publicfunctiongetEmail(): string { return$this->email; }
}
$user = Json::decodeAs('{"username":"ibrahim","email":"a@b.com"}', User::class);
echo$user->getUsername(); // ibrahim

Nested objects are resolved automatically via constructor type hints. Use #[JsonType] for arrays of objects:

useWebFiori\Json\JsonType;
class Order {
publicfunction__construct(
privateUser$customer,
#[JsonType(LineItem::class, isArray: true)]
privatearray$items
) {}
}
$order = Json::decodeAs($jsonString, Order::class);
$order->getCustomer(); // User instance$order->getItems(); // LineItem[] array

Runtime type mapping without attributes:

$json = Json::decode($jsonString);
$json->setTypeMap([
'customer' => User::class,
'items' => [LineItem::class],
]);
$json->get('customer'); // User instance$json->get('items'); // LineItem[] array

Saving to File

$json = newJson(['name' => 'Ibrahim', 'age' => 30]);
$json->toJsonFile('data', '/path/to/directory', true);
// Creates /path/to/directory/data.json

Converting to Array

The toArray() method converts a Json object to a plain PHP associative array without the overhead of encoding to a JSON string and decoding it back:

$json = newJson([
'name' => 'Ibrahim',
'age' => 30,
'active' => true,
]);
$address = newJson(['city' => 'Riyadh', 'country' => 'SA']);
$json->add('address', $address);
$array = $json->toArray();
// Result:// [// 'name' => 'Ibrahim',// 'age' => 30,// 'active' => true,// 'address' => [// 'city' => 'Riyadh',// 'country' => 'SA',// ],// ]

This is useful when passing structured data to functions expecting arrays, PHPUnit assertions, or merging with other arrays. See examples/11-to-array.php for more examples.

JSONx

JSONx is an IBM standard that represents JSON as XML:

$json = newJson(['name' => 'Ibrahim', 'age' => 30, 'isEmployed' => true]);
echo$json->toJSONxString();

Output:

<?xml version="1.0" encoding="UTF-8"?>
<json:objectxsi:schemaLocation="http://www.datapower.com/schemas/json jsonx.xsd"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
<json:stringname="name">Ibrahim</json:string>
<json:numbername="age">30</json:number>
<json:booleanname="isEmployed">true</json:boolean>
</json:object>

Error Handling

All errors throw \WebFiori\Json\JsonException:

try {
$json = Json::decode('{invalid json}');
} catch (\WebFiori\Json\JsonException$e) {
echo$e->getMessage();
}

API Reference

Classes

ClassDescription
JsonMain class for building, reading, and deserializing JSON data
JsonIInterface for custom object serialization
JsonConverterHandles serialization to JSON and JSONx strings
JsonDeserializerHandles typed deserialization of JSON into objects
PropertyRepresents a single JSON property
CaseConverterConverts property names between naming styles
JsonTypesConstants for JSON data types
JsonExceptionException thrown on JSON errors

Attributes

AttributeTargetDescription
#[JsonIgnore]Method, PropertyExclude from serialization
#[JsonProperty(name)]Method, PropertyOverride output name
#[JsonType(class, isArray)]Parameter, PropertySpecify type for deserialization

Key Methods — Json

MethodDescription
add(string $key, mixed $value, bool $arrayAsObj = false): boolAdd any value
addString(string $key, string $val): boolAdd a string
addNumber(string $key, int|float $value): boolAdd a number
addBoolean(string $key, bool $val = true): boolAdd a boolean
addNull(string $key): boolAdd a null value
addArray(string $key, array $value, bool $asObject = false): boolAdd an array
addObject(string $key, object &$val): boolAdd an object
get(string $key): mixedGet a property value
hasKey(string $key): boolCheck if a key exists
remove(string $key): ?PropertyRemove a property
setPropsStyle(string $style, string $lettersCase = 'same'): voidChange naming style
setIsFormatted(bool $bool): voidToggle formatted output
setTypeMap(array $map): voidSet type map for typed deserialization via get()
toJSONString(): stringGet JSON string
toJSONxString(): stringGet JSONx string
toArray(): arrayGet plain PHP associative array
toJsonFile(string $fileName, string $path, bool $override = false): voidSave to file
Json::decode(string $jsonStr): JsonDecode a JSON string
Json::decodeAs(string $jsonStr, string $className): objectDecode and hydrate a typed object
Json::fromJsonFile(string $path): JsonLoad from a JSON file
Json::setDefaults(?string $style, ?string $case, ?bool $formatted): voidSet application-wide defaults
Json::resetDefaults(): voidReset to library defaults

Testing

# Install dependencies
composer install
# Run tests
composer test

Contributing

Contributions are welcome! Please open an issue or submit a pull request on GitHub.

License

This library is licensed under the MIT License. See the LICENSE file for more details.

Support

If you encounter any issues, please open an issue on GitHub.

Changelog

See CHANGELOG.md for a list of changes.

About

A JSON helper classes for creating JSON strings in PHP.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

8 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

WebFiori Json

A PHP library for creating and parsing JSON and JSONx strings. Supports all PHP scalar types, arrays, and objects with flexible property naming styles.

PHP 8.1+

Table of Contents

Key Features

  • Create well-formatted JSON strings from any PHP value (scalars, arrays, objects)
  • Decode JSON strings and files into Json objects
  • Typed deserialization via Json::decodeAs() with nested object hydration
  • Flexible property naming styles: camelCase, kebab-case, snake_case, or none
  • Letter case control: same, upper, lower
  • Custom object serialization via the JsonI interface
  • Auto-mapping of plain objects via public getter methods and public properties
  • Auto-detection of associative arrays as JSON objects
  • Attribute-based control: #[JsonProperty], #[JsonIgnore], #[JsonType]
  • Application-wide defaults via Json::setDefaults()
  • JSONx output (XML representation of JSON)
  • Save JSON output directly to a file

Supported PHP Versions

Build Status

Installation

composer require webfiori/jsonx

Quick Start

useWebFiori\Json\Json;
$json = newJson([
'name' => 'Ibrahim',
'age' => 30,
'married' => false,
'score' => 9.5,
'notes' => null,
]);
echo$json;

Output:

{"name":"Ibrahim","age":30,"married":false,"score":9.5,"notes":null}

You can also build the object incrementally:

$json = newJson();
$json->addString('name', 'Ibrahim');
$json->addNumber('age', 30);
$json->addBoolean('married', false);
$json->addNull('notes');

Usage

Working With Arrays

$json = newJson();
// Indexed array$json->addArray('tags', ['php', 'json', 'api']);
// Associative arrays are automatically encoded as JSON objects$json->addArray('address', ['city' => 'Riyadh', 'country' => 'SA']);
echo$json;

Output:

{"tags":["php","json","api"],"address":{"city":"Riyadh","country":"SA"}}

Working With Objects

Using JsonI Interface

Implement JsonI to fully control how an object is serialized:

useWebFiori\Json\Json;
useWebFiori\Json\JsonI;
class User implements JsonI {
publicfunction__construct(
privatestring$username,
privatestring$email
) {}
publicfunctiontoJSON(): Json {
returnnewJson(['username' => $this->username, 'email' => $this->email]);
}
}
$json = newJson();
$json->addObject('user', newUser('ibrahim', 'ibrahim@example.com'));
echo$json;

Output:

{"user":{"username":"ibrahim","email":"ibrahim@example.com"}}

Auto-Mapping Objects

Objects that don't implement JsonI are mapped automatically using:

  1. Public getter methods — any zero-parameter method prefixed with get is called. The property name is derived by stripping get (e.g. getName()Name with style none, or name with style camel).
  2. Public properties — extracted via reflection and added as-is.

Use #[JsonIgnore] to exclude specific getters or properties, and #[JsonProperty] to override the output name:

useWebFiori\Json\Json;
useWebFiori\Json\JsonIgnore;
useWebFiori\Json\JsonProperty;
class Product {
#[JsonProperty('product_sku')]
publicstring$sku = 'ABC-001';
#[JsonIgnore]
publicstring$internalCode = 'X-99';
privatestring$name;
privatefloat$price;
publicfunction__construct(string$name, float$price) {
$this->name = $name;
$this->price = $price;
}
publicfunctiongetName(): string { return$this->name; }
publicfunctiongetPrice(): float { return$this->price; }
#[JsonProperty('on_sale')]
publicfunctiongetAvailable(): bool { returntrue; }
#[JsonIgnore]
publicfunctiongetSecretMargin(): float { return0.42; }
}
$json = newJson([], 'snake');
$json->addObject('product', newProduct('Keyboard', 49.99));
echo$json;

Output:

{"product":{"name":"Keyboard","price":49.99,"on_sale":true,"product_sku":"ABC-001"}}

Property Naming Styles

Four naming styles are supported: none (default), camel, snake, kebab.
Three letter cases are supported: same (default), upper, lower.

$data = ['first-name' => 'Ibrahim', 'last-name' => 'Al-Shikh'];
echonewJson($data, 'none') . "\n"; // {"first-name":"Ibrahim","last-name":"Al-Shikh"}echonewJson($data, 'camel') . "\n"; // {"firstName":"Ibrahim","lastName":"Al-Shikh"}echonewJson($data, 'snake') . "\n"; // {"first_name":"Ibrahim","last_name":"Al-Shikh"}echonewJson($data, 'kebab') . "\n"; // {"first-name":"Ibrahim","last-name":"Al-Shikh"}

Set application-wide defaults:

Json::setDefaults(style: 'camel', case: 'lower', formatted: false);

Decoding JSON

Decode a JSON string:

$json = Json::decode('{"name":"Ibrahim","age":30}');
echo$json->get('name'); // Ibrahim

Read from a file:

$json = Json::fromJsonFile('/path/to/file.json');

Typed Deserialization

Deserialize JSON directly into typed objects:

class User {
publicfunction__construct(
privatestring$username,
privatestring$email
) {}
publicfunctiongetUsername(): string { return$this->username; }
publicfunctiongetEmail(): string { return$this->email; }
}
$user = Json::decodeAs('{"username":"ibrahim","email":"a@b.com"}', User::class);
echo$user->getUsername(); // ibrahim

Nested objects are resolved automatically via constructor type hints. Use #[JsonType] for arrays of objects:

useWebFiori\Json\JsonType;
class Order {
publicfunction__construct(
privateUser$customer,
#[JsonType(LineItem::class, isArray: true)]
privatearray$items
) {}
}
$order = Json::decodeAs($jsonString, Order::class);
$order->getCustomer(); // User instance$order->getItems(); // LineItem[] array

Runtime type mapping without attributes:

$json = Json::decode($jsonString);
$json->setTypeMap([
'customer' => User::class,
'items' => [LineItem::class],
]);
$json->get('customer'); // User instance$json->get('items'); // LineItem[] array

Saving to File

$json = newJson(['name' => 'Ibrahim', 'age' => 30]);
$json->toJsonFile('data', '/path/to/directory', true);
// Creates /path/to/directory/data.json

Converting to Array

The toArray() method converts a Json object to a plain PHP associative array without the overhead of encoding to a JSON string and decoding it back:

$json = newJson([
'name' => 'Ibrahim',
'age' => 30,
'active' => true,
]);
$address = newJson(['city' => 'Riyadh', 'country' => 'SA']);
$json->add('address', $address);
$array = $json->toArray();
// Result:// [// 'name' => 'Ibrahim',// 'age' => 30,// 'active' => true,// 'address' => [// 'city' => 'Riyadh',// 'country' => 'SA',// ],// ]

This is useful when passing structured data to functions expecting arrays, PHPUnit assertions, or merging with other arrays. See examples/11-to-array.php for more examples.

JSONx

JSONx is an IBM standard that represents JSON as XML:

$json = newJson(['name' => 'Ibrahim', 'age' => 30, 'isEmployed' => true]);
echo$json->toJSONxString();

Output:

<?xml version="1.0" encoding="UTF-8"?>
<json:objectxsi:schemaLocation="http://www.datapower.com/schemas/json jsonx.xsd"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
<json:stringname="name">Ibrahim</json:string>
<json:numbername="age">30</json:number>
<json:booleanname="isEmployed">true</json:boolean>
</json:object>

Error Handling

All errors throw \WebFiori\Json\JsonException:

try {
$json = Json::decode('{invalid json}');
} catch (\WebFiori\Json\JsonException$e) {
echo$e->getMessage();
}

API Reference

Classes

ClassDescription
JsonMain class for building, reading, and deserializing JSON data
JsonIInterface for custom object serialization
JsonConverterHandles serialization to JSON and JSONx strings
JsonDeserializerHandles typed deserialization of JSON into objects
PropertyRepresents a single JSON property
CaseConverterConverts property names between naming styles
JsonTypesConstants for JSON data types
JsonExceptionException thrown on JSON errors

Attributes

AttributeTargetDescription
#[JsonIgnore]Method, PropertyExclude from serialization
#[JsonProperty(name)]Method, PropertyOverride output name
#[JsonType(class, isArray)]Parameter, PropertySpecify type for deserialization

Key Methods — Json

MethodDescription
add(string $key, mixed $value, bool $arrayAsObj = false): boolAdd any value
addString(string $key, string $val): boolAdd a string
addNumber(string $key, int|float $value): boolAdd a number
addBoolean(string $key, bool $val = true): boolAdd a boolean
addNull(string $key): boolAdd a null value
addArray(string $key, array $value, bool $asObject = false): boolAdd an array
addObject(string $key, object &$val): boolAdd an object
get(string $key): mixedGet a property value
hasKey(string $key): boolCheck if a key exists
remove(string $key): ?PropertyRemove a property
setPropsStyle(string $style, string $lettersCase = 'same'): voidChange naming style
setIsFormatted(bool $bool): voidToggle formatted output
setTypeMap(array $map): voidSet type map for typed deserialization via get()
toJSONString(): stringGet JSON string
toJSONxString(): stringGet JSONx string
toArray(): arrayGet plain PHP associative array
toJsonFile(string $fileName, string $path, bool $override = false): voidSave to file
Json::decode(string $jsonStr): JsonDecode a JSON string
Json::decodeAs(string $jsonStr, string $className): objectDecode and hydrate a typed object
Json::fromJsonFile(string $path): JsonLoad from a JSON file
Json::setDefaults(?string $style, ?string $case, ?bool $formatted): voidSet application-wide defaults
Json::resetDefaults(): voidReset to library defaults

Testing

# Install dependencies
composer install
# Run tests
composer test

Contributing

Contributions are welcome! Please open an issue or submit a pull request on GitHub.

License

This library is licensed under the MIT License. See the LICENSE file for more details.

Support

If you encounter any issues, please open an issue on GitHub.

Changelog

See CHANGELOG.md for a list of changes.

About

A JSON helper classes for creating JSON strings in PHP.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

8 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages