🔗 Project on GitHub
View the full source code and contribute on GitHub:
https://github.com/BcommeBois/oihana-php-schema
✨ Key Features
- ✔️ Full modeling of Schema.org entities
- 🧩 Automatic JSON-LD serialization (
JsonSerializable) - 🪄 Recursive object hydration (including nested types and union types)
- 🧠 Internal reflection system (
oihana\reflections) - 🎯 Safe property access via constants (e.g.
Prop::NAME) - 📚 Extensible architecture for custom ontologies
- 🔐 Support for ArangoDB metadata (
_id,_key,_rev,_from,_to)
📦 Installation
This library requires PHP 8.4+ and is installed via Composer:
composer require oihana/php-schema
🚀 Quick Example
Here is a basic usage example using Person and PostalAddress:
use org\schema\Person;
use org\schema\PostalAddress;
use org\schema\constants\Prop;
$person = new Person
([
Prop::ID => '2555' ,
Prop::NAME => 'John Doe' ,
Prop::ADDRESS => new PostalAddress
([
Prop::STREET_ADDRESS => '2 chemin des Vergers' ,
Prop::POSTAL_CODE => '49170'
])
]);
echo json_encode($person, JSON_PRETTY_PRINT);
JSON-LD output:
{
"@type": "Person",
"@context": "https://schema.org",
"id": "2555",
"name": "John Doe",
"address":
{
"@type": "PostalAddress",
"@context": "https://schema.org",
"streetAddress": "2 chemin des Vergers",
"postalCode": "49170"
}
}
🧠 Internal Architecture
All schema entities inherit from a base class Thing, which handles metadata, public properties, and JSON-LD serialization logic:
- Constructor: Hydrates the object via array or stdClass
- JSON Serialization: Reflects public properties and adds
@typeand@context - Reflection helpers: Provided via internal
ReflectionTrait
🔐 Property Constants
The Prop class enumerates all known schema properties as constants for safe access:
use org\schema\constants\Prop;
$event = new Event
([
Prop::NAME => 'Oihana Conf 2025',
Prop::LOCATION => new Place( [ Prop::NAME => 'Nantes' ] )
]);
✅ Running Unit Tests
Run all unit tests:
composer test
Run a specific test:
composer test ./tests/org/schema/ThingTest.php
📄 License
This project is licensed under the Mozilla Public License 2.0 (MPL-2.0).
👤 About the Author
- Name: Marc ALCARAZ (aka eKameleon)
- Website: www.ooop.fr
- Email: marc@ooop.fr
📚 Documentation
Full project documentation is available at:
https://bcommebois.github.io/oihana-php-schema
Explore namespaces:
org\schema\, org\schema\traits, org\schema\constants
for types, behaviors and property constants.
A complete developer guide is coming soon (UML, object maps, property references).
🧩 Advanced Usage
Union-typed properties
Some properties accept multiple types. For instance, publisher may be a string, a Person, or an Organization.
use org\schema\CreativeWork;
use org\schema\Person;
use org\schema\Organization;
use org\schema\constants\Prop;
$post = new CreativeWork([
Prop::NAME => 'Release Notes',
Prop::PUBLISHER => new Organization([ Prop::NAME => 'Oihana' ])
]);
Arrays and nested entities
Compose objects with arrays of other entities via typed public properties.
use org\schema\Thing;
use org\schema\constants\Prop;
$parent = new Thing([
Prop::NAME => 'Bundle',
Prop::HAS_PART => [
new Thing([ Prop::NAME => 'Part A' ]),
new Thing([ Prop::NAME => 'Part B' ]),
],
]);
JSON-LD metadata for ArangoDB
Base Thing supports ArangoDB-style metadata fields to facilitate graph storage: _key, _id, _rev, _from, _to.
use org\schema\Thing;
$edge = new Thing([
'_from' => 'users/2555',
'_to' => 'groups/42',
]);
Deep/recursive hydration
The constructor copies provided values into public properties. For deep graphs and automatic casting,
you can rely on the internal reflection utilities exposed by oihana/php-reflect.
Typical usage is to call a reflection-based hydrate() to materialize nested arrays into value objects.
🧱 Extending the Library
Extend org\schema\Thing (or a more specific class) and declare typed public properties. You can also add constants alongside org\schema\constants\Prop.
namespace app\domain;
use org\schema\Thing;
class CustomAsset extends Thing
{
public ?string $slug;
public ?string $category;
}
⚙️ Installation Notes
- Requires PHP 8.4+.
- Depends on
oihana/php-coreandoihana/php-reflect. If your project enforces stable-only, consider setting"minimum-stability": "dev"and"prefer-stable": truewhile these libraries are pre-release.
🤝 Contributing
Contributions are welcome:
- Open an issue to discuss significant changes before a PR.
- Add tests for bug fixes and new features.
- Keep code style consistent and types explicit.
composer install composer test composer doc
🔒 Security
If you discover a security vulnerability, email marc@ooop.fr. Do not open a public issue.
📜 Changelog
See CHANGELOG.md for notable changes.
🔗 Related Packages
- oihana/php-core – core helpers and utilities used by this library
- oihana/php-reflect – reflection and hydration utilities
🛠️ Generate the Documentation
We use phpDocumentor to generate this site.
composer doc
❓ FAQ
- Why JSON-LD? It’s schema-friendly, web-native, and search-engine friendly.
- Can I output plain arrays? Yes,
jsonSerialize()returns arrays you can pass to any encoder. - How to ignore nulls? Serialization automatically removes null values.
🧮 JSON Schema Generation
Generate JSON Schemas from the typed public properties of your classes.
Single class (example: Place):
composer schema:place
All classes under src/org/schema:
composer schemas:all
Schemas are written to schemas/*.schema.json.
Union types are represented as oneOf; class types are emitted as $ref into local $defs.
Requires Composer autoload; run composer dump-autoload -o if classes are not found.