PHPackages                             oihana/php-schema - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. oihana/php-schema

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

oihana/php-schema
=================

The Oihana PHP Schema library

1.2.0(1w ago)01.0k10MPL-2.0PHPPHP &gt;=8.4CI passing

Since Aug 13Pushed 1w agoCompare

[ Source](https://github.com/BcommeBois/oihana-php-schema)[ Packagist](https://packagist.org/packages/oihana/php-schema)[ Docs](https://github.com/BcommeBois/oihana-php-schema)[ RSS](/packages/oihana-php-schema/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (10)Versions (5)Used By (10)

Oihana PHP - Schema
===================

[](#oihana-php---schema)

[![Oihana PHP Schema](https://raw.githubusercontent.com/BcommeBois/oihana-php-schema/refs/heads/main/assets/images/oihana-php-schema-logo-inline-512x160.png)](https://raw.githubusercontent.com/BcommeBois/oihana-php-schema/refs/heads/main/assets/images/oihana-php-schema-logo-inline-512x160.png)

Oihana Schema is a PHP library that provides an object-oriented implementation of the [Schema.org](https://www.schema.org) vocabulary. It is designed to encapsulate structured data using strongly typed value objects, with automatic serialization and hydration features.

[![Latest Version](https://camo.githubusercontent.com/bacf52d00f26dc8040e4940a11d57eb5e3ef6ccf962f11928e71199cc5ac32cf/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6f6968616e612f7068702d736368656d612e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/oihana/php-schema)
[![Total Downloads](https://camo.githubusercontent.com/17bf0a15dc8ca2643962eb95d25f90fb070881a0691b34abc5297e705712650a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6f6968616e612f7068702d736368656d612e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/oihana/php-schema)
[![License](https://camo.githubusercontent.com/f84ba0fdd281acf3683404005aae5bda4c3766b65ad948477c53dc13bf7e4ead/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6f6968616e612f7068702d736368656d612e7376673f7374796c653d666c61742d737175617265)](LICENSE)

This library is ideal for representing database records or REST API resources in a structured, semantically rich way, compatible with JSON-LD and linked data ecosystems.

✨ Key Features
--------------

[](#-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. Schema::NAME)
- 📚 Extensible architecture for custom ontologies
- 🔐 Support for ArangoDB metadata (\_id, \_key, \_rev, \_from, \_to)

📦 Installation
--------------

[](#-installation)

> **Requires [PHP 8.4+](https://php.net/releases/)**

Install via [Composer](https://getcomposer.org):

```
composer require oihana/php-schema
```

🚀 Quick Example
---------------

[](#-quick-example)

Simple usage

```
use org\schema\Person;
use org\schema\PostalAddress;
use org\schema\constants\Schema;

$person = new Person
([
    Schema::ID      => '2555',
    Schema::NAME    => 'John Doe',
    Schema::ADDRESS => new PostalAddress
    ([
        Schema::STREET_ADDRESS => '2 chemin des Vergers',
        Schema::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"
  }
}
```

🗂️ Schemas overview
-------------------

[](#️-schemas-overview)

The library exposes three top-level namespaces. Each row below links to a dedicated wiki guide (English / Français) that lists the classes, gives a code example and points to the source.

NamespaceWhat it coversClassesWiki guide`org\schema`Full Schema.org vocabulary — typed value objects for `Thing`, `Person`, `Place`, `Event`, `Product`, `Offer`, the complete `Action` hierarchy, creative works, organizations, services, enumerations.~400[🇬🇧 EN](wiki/en/schema-org/README.md) · [🇫🇷 FR](wiki/fr/schema-org/README.md)`xyz\oihana\schema\auth`OAuth2/OIDC clients, sessions, keyfiles, users, roles, permissions, RBAC policies, Casbin helpers, JWT claims registry.15[🇬🇧 EN](wiki/en/oihana-auth.md) · [🇫🇷 FR](wiki/fr/oihana-auth.md)`xyz\oihana\schema\business`Account ↔ business-world link: `BusinessIdentity` (typed account/entity link) and `UserProfile` (creation-time provisioning template).2[🇬🇧 EN](wiki/en/oihana-business.md) · [🇫🇷 FR](wiki/fr/oihana-business.md)`xyz\oihana\schema\http`Structured HTTP request metadata: `UserAgentInfo` (browser, OS, device class, bot flag).1[🇬🇧 EN](wiki/en/oihana-http.md) · [🇫🇷 FR](wiki/fr/oihana-http.md)`xyz\oihana\schema\places`Operational locations: `Site`, `Office`, `Warehouse`, `JobSite`.4[🇬🇧 EN](wiki/en/oihana-places.md) · [🇫🇷 FR](wiki/fr/oihana-places.md)`xyz\oihana\schema`Cross-cutting Oihana types: `Pagination`, `Log`, `AuditAction`, audit enumerations.3 + enums[🇬🇧 EN](wiki/en/oihana-core.md) · [🇫🇷 FR](wiki/fr/oihana-core.md)`com\progress\schema`OpenEdge Progress SQL `SYS%` system catalog: tables, columns, indexes, views, users, privileges, constraints, sequences, triggers, procedures, data types.16[🇬🇧 EN](wiki/en/openedge-progress.md) · [🇫🇷 FR](wiki/fr/openedge-progress.md)Every entity extends `org\schema\Thing`, so they all share the same JSON-LD serialization, hydration and ArangoDB metadata. Sub-namespaces override the `CONTEXT` constant so downstream consumers can tell them apart:

NamespaceJSON-LD `@context``org\schema``https://schema.org``xyz\oihana\schema*``https://schema.oihana.xyz``com\progress\schema``https://schema.progress.com`🧠 Internal Architecture
-----------------------

[](#-internal-architecture)

### Base class: Thing

[](#base-class-thing)

All entities extend the base class org\\schema\\Thing, which includes common Schema.org and metadata properties, as well as serialization logic:

The ThingTrait handles:

- Dynamic constructor from arrays or objects
- JSON-LD serialization via jsonSerialize()
- Reflection-based helpers from ReflectionTrait

#### Recursive Hydration

[](#recursive-hydration)

The internal **[Reflection::hydrate()](https://github.com/BcommeBois/oihana-php-system/blob/00552f088022ee2af836b011d0efc0c69ffeab63/src/oihana/reflections/Reflection.php#L42)** method builds full object graphs from associative arrays, including nested value objects and union types:

```
$person = $reflection->hydrate
([
    'name'    => 'Alice',
    'address' => [ 'streetAddress' => '123 Lilac Street' ]
], Person::class ) ;
```

🔐 Safe Property Access
----------------------

[](#-safe-property-access)

The org\\schema\\constants\\Schema class contains constant names for every property in the **Schema.org** ontology and its extensions:

```
use org\schema\constants\Schema;
use org\schema\Event;

$event = new Event
([
    Schema::NAME     => 'Oihana Conf 2025',
    Schema::LOCATION => new Place([ Schema::NAME => 'Nantes' ])
]);
```

Properties are grouped by logical trait namespaces (e.g. Thing, Person, Event, etc.) for auto-completion and modularity:

```
trait Thing
{
    const string NAME = 'name';
    const string URL  = 'url';
    const string ID   = 'id';
    // ...
}
```

📚 Documentation
---------------

[](#-documentation)

Two complementary sets of documentation are available:

- 📖 **Auto-generated API reference** (every class, property and method) — published at . Regenerate it locally with `composer doc`.
- ✍️ **Hand-written wiki** (concepts, guides, walkthroughs) — bilingual EN/FR under [`wiki/`](wiki/README.md):
    - 🇬🇧 [`wiki/en/README.md`](wiki/en/README.md) — English guides ([Getting started](wiki/en/getting-started.md))
    - 🇫🇷 [`wiki/fr/README.md`](wiki/fr/README.md) — Guides en français ([Démarrage rapide](wiki/fr/demarrage.md))

While the wiki grows, you can also explore the following namespaces directly:

- `org\schema\` for value objects
- `org\schema\traits` for logic traits
- `org\schema\constants` for property constants

✅ Running Unit Tests
--------------------

[](#-running-unit-tests)

To run all tests:

```
composer test
```

To run a specific test file:

```
composer test ./tests/org/schema/ThingTest.php
composer test ./tests/xyz/oihana/schema/PaginationTest.php
```

🧾 License
---------

[](#-license)

This project is licensed under the [Mozilla Public License 2.0 (MPL-2.0)](https://www.mozilla.org/en-US/MPL/2.0/).

👤 About the author
------------------

[](#-about-the-author)

- Author : Marc ALCARAZ (aka eKameleon)
- Mail :
- Website :

🛠️ Generate the Documentation
-----------------------------

[](#️-generate-the-documentation)

We use [phpDocumentor](https://phpdoc.org/) to generate the documentation into the ./docs folder.

### Usage

[](#usage)

Run the command :

```
composer doc
```

🧩 Advanced Usage
----------------

[](#-advanced-usage)

### Union-typed properties

[](#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\Schema;

$post = new CreativeWork
([
    Schema::NAME      => 'Release Notes',
    Schema::PUBLISHER => new Organization([ Schema::NAME => 'Oihana' ])
]);
```

### Arrays and nested entities

[](#arrays-and-nested-entities)

You can compose objects with arrays of other entities, leveraging the public-typed properties.

```
use org\schema\Thing;
use org\schema\constants\Schema;

$parent = new Thing
([
    Schema::NAME   => 'Bundle',
    Schema::HAS_PART =>
    [
        new Thing([ Schema::NAME => 'Part A' ]),
        new Thing([ Schema::NAME => 'Part B' ]),
    ],
]);
```

### JSON-LD metadata for ArangoDB

[](#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

[](#deeprecursive-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` (see developer docs). A typical approach is to call a reflection-based `hydrate()` to materialize nested arrays into value objects.

🧱 Extending the Library
-----------------------

[](#-extending-the-library)

Define your own types by extending `org\schema\Thing` or a more specific class, and add your public-typed properties. You can also define constants alongside `org\schema\constants\Schema` for safer access.

```
namespace app\domain;

use org\schema\Thing;

class CustomAsset extends Thing
{
    public ?string $slug;
    public ?string $category;
}
```

⚙️ Installation Notes
---------------------

[](#️-installation-notes)

- This package requires PHP 8.4+.
- It depends on `oihana/php-core` and `oihana/php-reflect`. If your project enforces stable versions only, you may need to allow dev versions while these libraries are pre-release:
    - In your root composer.json: set `"minimum-stability": "dev"` and `"prefer-stable": true` if needed.

🤝 Contributing
--------------

[](#-contributing)

Contributions are welcome! Please:

- Open an issue to discuss significant changes before submitting a PR.
- Add tests when fixing a bug or adding a feature.
- Keep code style consistent and types explicit.

Local setup:

```
composer install
composer test
composer doc
```

🔒 Security
----------

[](#-security)

If you discover a security vulnerability, please email `marc@ooop.fr`. Do not open a public issue for security reports.

📜 Changelog
-----------

[](#-changelog)

See `CHANGELOG.md` for notable changes.

🔗 Related Packages
------------------

[](#-related-packages)

- [oihana/php-core](https://github.com/BcommeBois/oihana-php-core) – core helpers and utilities used by this library
- [oihana/php-reflect](https://github.com/BcommeBois/oihana-php-reflect) – reflection and hydration utilities

❓ FAQ
-----

[](#-faq)

- Why JSON-LD?
    It’s a web-native, schema-friendly format that plays well with linked data and search engines.
- Can I output plain arrays?
    Yes, `jsonSerialize()` returns arrays that you can pass to any JSON encoder.
- How to ignore nulls?
    Serialization automatically removes null values.

🧮 JSON Schema Generation
------------------------

[](#-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
```

Details:

- 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).

### Output layout and cleanup

[](#output-layout-and-cleanup)

- Namespaces map to folders under `schemas/`:
    - `org\schema\...` → `schemas/org/schema/.../*.schema.json`
    - `xyz\oihana\schema\...` → `schemas/xyz/oihana/schema/.../*.schema.json`
- Running `composer schemas:all` first deletes previous `*.schema.json` under `schemas/` to avoid stale files, then regenerates everything.

### Array unions handling

[](#array-unions-handling)

When a property type includes `array` plus other types (e.g. `string|ImageObject|array|null`), the generator emits:

- direct options for `string`, `ImageObject`, `null` (if present)
- and an `array` variant whose `items` use a `oneOf` of the non-array types (here `ImageObject` and `string`).

###  Health Score

50

↑

FairBetter than 95% of packages

Maintenance98

Actively maintained with recent releases

Popularity20

Limited adoption so far

Community16

Small or concentrated contributor base

Maturity57

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~105 days

Total

4

Last Release

7d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/d234506e51778dd3d1d61b6c2af6f294ff963651b4aa509b595d3d2a77b7d89b?d=identicon)[ooop](/maintainers/ooop)

---

Top Contributors

[![ekameleon](https://avatars.githubusercontent.com/u/749032?v=4)](https://github.com/ekameleon "ekameleon (219 commits)")

---

Tags

phpschema

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/oihana-php-schema/health.svg)

```
[![Health](https://phpackages.com/badges/oihana-php-schema/health.svg)](https://phpackages.com/packages/oihana-php-schema)
```

###  Alternatives

[imanghafoori/laravel-anypass

A minimal yet powerful package to help you in development.

21623.4k](/packages/imanghafoori-laravel-anypass)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
