accredifysg/php-json-ld

A PHP implementation of the JSON-LD 1.1 specification.

Maintainers

Package info

github.com/Accredifysg/PHP-JSON-LD

Homepage

pkg:composer/accredifysg/php-json-ld

Transparency log

Statistics

Installs: 367

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v2.1.0 2026-08-13 08:14 UTC

README

A PHP implementation of the JSON-LD 1.1 specification.

PHP-JSON-LD implements all six JSON-LD 1.1 processing algorithms — Expansion, Compaction, Flattening, Serialize to RDF (toRdf), RDF to JSON-LD (fromRdf), and Framing — validated against the official W3C test suites (1,287 of 1,302 tests passing, with Compaction and Flattening fully conformant) and cross-checked against reference implementations for identical canonical RDF output. The public API is stable and the project follows Semantic Versioning.

Highlights

  • Complete algorithm coverage of the JSON-LD 1.1 Processing Algorithms and API and JSON-LD 1.1 Framing.
  • Conformance gated in CI against the official W3C suites: any regression — or a documented blocker that silently starts passing — fails the build.
  • Cross-implementation interoperability: RDF output is verified against RDFC-1.0 canonical N-Quads goldens generated by jsonld.js over realistic verifiable-credential documents, so signatures computed over this library's output verify in other conformant processors (see tests/Interop).
  • Pluggable document loading: implement one DocumentLoader interface to serve known @context URLs from local resources — recommended for verifiable-credential pipelines — or use the bundled PSR-18 HTTP loader.
  • No mandatory HTTP dependency: bring your own PSR-18 client, or none.

Installation

composer require accredifysg/php-json-ld

Requires PHP 8.2+. The bundled HttpDocumentLoader needs a PSR-18 HTTP client and PSR-17 request factory (e.g. guzzlehttp/guzzle + guzzlehttp/psr7); alternatively, implement Accredify\JsonLd\Contracts\DocumentLoader yourself and no HTTP client is required.

Usage

use Accredify\JsonLd\JsonLdProcessor;
use Accredify\JsonLd\Loaders\CachingDocumentLoader;
use Accredify\JsonLd\Loaders\HttpDocumentLoader;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\HttpFactory;

$loader = new CachingDocumentLoader(
    new HttpDocumentLoader(new Client, new HttpFactory),
);

$processor = new JsonLdProcessor($loader);

$expanded = $processor->expand($document);
$compacted = $processor->compact($expanded->toArray(), $context)->toArray();
$nQuads = $processor->toRdf($document)->toNQuads();

To serve known contexts from local files (recommended for verifiable credentials), implement Accredify\JsonLd\Contracts\DocumentLoader. See tests/Interop/Support/FixtureDocumentLoader.php for a compact example.

Framing note: a frame's {} wildcard cannot be represented in PHP's associative-array model (it decodes identically to []), so the framing API treats an empty frame value as match none and accepts the documented Expansion::FRAME_WILDCARD sentinel for a wildcard.

Conformance

The package is tested against the official W3C JSON-LD 1.1 test suite (git submodule at tests/w3c/; harness documented in tests/W3c/README.md).

Algorithm Spec W3C suite Passing Conformance
Expansion §5.5 385 381 4 documented blockers
Compaction §5.6 246 246 100%
Serialize to RDF (toRdf) §7 467 463 4 documented blockers
Flattening §4.6 58 58 100%
RDF to JSON-LD (fromRdf) §4.9 54 50 4 documented blockers
Framing framing §4 92 89 3 documented blockers

Totals: 1,287 / 1,302 passing. The 15 residual non-conformances are negative-test, non-normative, or environment limits, carried as an explicit expected-failure allowlist (tests/W3c/KnownBlockers.php) that gates CI in both directions — a new regression fails the build, and so does a listed blocker that starts passing:

  • #tc032 / #tc033unused embedded contexts aren't validated (negative tests)
  • #ter56 — redefining the @context keyword isn't rejected (negative test)
  • #t0122 (expand only) — keyword-shaped (@) IRIs are dropped rather than kept as {@id: null} (non-normative)
  • #tjs10 (toRdf only) — JSON-literal structural canonicalization differs (PHP cannot distinguish {} from [])
  • #t0008 / #tli03 (fromRdf) — list-of-lists conversion; single-level lists are fully supported
  • #tdi11 / #tdi12 (fromRdf, non-normative) — compound-literal direction folding
  • #t0010 (framing) — compaction safe-mode rejects dcterms:creator as an IRI confused with the dcterms prefix (the reference processor errors here too)
  • #t0045 (framing) — @language case-normalization (expansion preserves case, which the signature-critical toRdf bytes depend on)
  • #t0059 (framing) — the legacy @embed: @last mode (the @once default is implemented)
composer test        # unit tests (includes the interop corpus)
composer test:w3c    # the W3C conformance suites

Implementation report

A W3C EARL implementation report is generated for each release and submitted to the JSON-LD 1.1 implementation report. To regenerate it:

vendor/bin/pest --testsuite W3C --log-junit w3c-junit.xml
php scripts/generate-earl-report.php w3c-junit.xml <version> > reports/php-json-ld-earl.ttl

Tests marked specVersion: json-ld-1.0 are excluded from the report, matching the consolidated report's JSON-LD 1.1 scope.

Interoperability

The W3C suite alone cannot catch a processor that is consistently wrong: internal sign/verify round-trips recompute the same dataset on both sides, and a divergence only surfaces when another implementation checks the signature. tests/Interop closes that gap with realistic VC 2.0 and Open Badges v3 documents whose RDFC-1.0 canonical N-Quads — the exact bytes an eddsa-rdfc-2022 proof is computed over — are pinned to goldens generated by jsonld.js and compared as datasets on every CI run.

Development notes

tests/Algorithms/Characterization/ holds JSON snapshots of the expander's output over sample verifiable-credential documents. They are not a spec-conformance reference; they pin behaviour so any change to expansion output lands as a reviewable diff, to be paired with matching updates in downstream consumers (e.g. signed-credential fixtures).

License

MIT © Accredify