PHPackages                             amateescu/prov - 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. [Parsing &amp; Serialization](/categories/parsing)
4. /
5. amateescu/prov

ActiveLibrary[Parsing &amp; Serialization](/categories/parsing)

amateescu/prov
==============

PHP implementation of the W3C Provenance Data Model (PROV-DM)

1.0.0(1mo ago)11MITPHPPHP ^8.4CI passing

Since Apr 23Pushed 3w ago1 watchersCompare

[ Source](https://github.com/amateescu/prov)[ Packagist](https://packagist.org/packages/amateescu/prov)[ RSS](/packages/amateescu-prov/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (4)Versions (2)Used By (0)

prov: W3C Provenance for PHP
============================

[](#prov-w3c-provenance-for-php)

[![Release](https://camo.githubusercontent.com/1787e47971fe9bba96f42275afa8ad4a06e5c0601f331d12d5e02ea526210858/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f616d617465657363752f70726f762e737667)](https://packagist.org/packages/amateescu/prov)[![CI](https://github.com/amateescu/prov/actions/workflows/ci.yml/badge.svg)](https://github.com/amateescu/prov/actions/workflows/ci.yml)

PHP implementation of the [W3C Provenance Data Model (PROV-DM)](https://www.w3.org/TR/prov-dm/).

PROV-DM describes where things come from: **entities** (things you care about), **activities** (things that happen), and **agents** (who's responsible). Relations like `wasGeneratedBy` and `wasAttributedTo` connect them to form a provenance graph.

PROV-DM fits data lineage, audit trails, scientific-workflow provenance, attribution graphs, and any case where you need to record where information came from.

This library provides a fluent builder for assembling that graph, round-trip serializers for [PROV-JSON](https://www.w3.org/Submission/prov-json/), [PROV-N](https://www.w3.org/TR/prov-n/), and [PROV-XML](https://www.w3.org/TR/prov-xml/) (plus serialize-only [PROV-JSONLD](https://www.w3.org/Submission/prov-jsonld/)), document operations (`merge`, `flatten`, semantic equality), and a partial [PROV-CONSTRAINTS](https://www.w3.org/TR/prov-constraints/) validator.

Requirements
------------

[](#requirements)

- PHP 8.4+
- `ext-dom` (only if you use `XmlSerializer`)

Installation
------------

[](#installation)

```
composer require amateescu/prov

```

Quick start
-----------

[](#quick-start)

```
use Prov\Format;
use Prov\Prov;

$builder = Prov::documentBuilder();
$builder->namespace('ex', 'http://example.org/');
$builder->entity('ex:article');
$builder->activity('ex:writing', startTime: new DateTimeImmutable('2024-01-15'));
$builder->agent('ex:alice');
$builder->wasGeneratedBy(entity: 'ex:article', activity: 'ex:writing');
$builder->wasAssociatedWith(activity: 'ex:writing', agent: 'ex:alice');

$doc = $builder->build();

$json = Prov::serialize($doc, Format::Json);
echo $json;
// Other formats: Format::ProvN, Format::Xml, Format::JsonLd.

$parsed = Prov::deserialize($json, Format::Json);
```

> **Always pass relation arguments by name.** PROV-DM fixes a per-relation positional order that does *not* follow subject-before-object. `wasGeneratedBy` takes `(entity, activity)` but `used` takes `(activity, entity)`: the two sit in opposite orders even though they connect the same two records. Positional calls silently invert the relation:
>
> ```
> // These two lines describe DIFFERENT facts, even though both identifiers are the same:
> $builder->wasGeneratedBy('ex:article', 'ex:writing'); // article wasGeneratedBy writing ✓
> $builder->used('ex:article', 'ex:writing');           // article used writing ✗ (reversed)
>
> // Always use named arguments:
> $builder->wasGeneratedBy(entity: 'ex:article', activity: 'ex:writing');
> $builder->used(activity: 'ex:writing', entity: 'ex:article');
> ```

Format support
--------------

[](#format-support)

FormatSerializeDeserializePROV-JSONyesyesPROV-NyesyesPROV-XMLyesyesPROV-JSONLDyesno (would require an RDF-aware parser)Document operations
-------------------

[](#document-operations)

```
use Prov\Operation\DocumentOperations;
use Prov\Operation\DocumentComparator;

$merged = DocumentOperations::merge($docA, $docB);
$flat = DocumentOperations::flatten($docWithBundles);            // throws if Mentions present
$flat = DocumentOperations::flattenDroppingMentions($docWithBundles);

DocumentComparator::equals($a, $b);  // structural (semantic) equality
```

Validation
----------

[](#validation)

```
$result = Prov::validate($document);

if (!$result->isValid()) {
    foreach ($result->getViolations() as $violation) {
        echo "[C{$violation->constraintId}] {$violation->message}\n";
    }
}

// Or throw if the document has any violations:
Prov::validate($document)->throwIfInvalid();  // raises ConstraintViolationException
```

Coverage is partial: rules that need transitive graph reasoning over derivation chains aren't implemented, so `isValid() === true` only means no checked rule was violated. Use `ConstraintValidator::implementedConstraints()` or `::unsupportedConstraints()` to see the exact set.

Builder tips
------------

[](#builder-tips)

**Blank nodes (anonymous records):**

```
$e = $builder->blank();          // _:b1
$builder->entity($e);
$builder->wasGeneratedBy(entity: $e, activity: 'ex:writing');
```

**Bundles:**

```
$builder
    ->entity('ex:e1')
    ->withBundle('ex:b1', fn ($b) => $b
        ->entity('ex:e2')
        ->wasGeneratedBy(entity: 'ex:e2', activity: 'ex:a1'))
    ->build();
```

`DocumentBuilder::build()` and `BundleBuilder::build()` are single-use; a second call throws `LogicException`.

Learn more
----------

[](#learn-more)

Every public class carries an inline docblock explaining what it's for. The most useful starting points:

- `Prov\Prov`: the facade used in the examples above
- `Prov\Builder\DocumentBuilder`: the full set of record and relation methods
- `Prov\Format`: supported serialization formats
- `Prov\Constraint\ConstraintValidator`: what each PROV-CONSTRAINTS rule checks

Development
-----------

[](#development)

Before submitting a PR, run `composer check` (format, lint, analyze, tests).

See also
--------

[](#see-also)

- [`trungdong/prov`](https://github.com/trungdong/prov): Python implementation of PROV-DM.
- [`lucmoreau/ProvToolbox`](https://github.com/lucmoreau/ProvToolbox): Java toolkit for PROV.

License
-------

[](#license)

This library is made available under the MIT License. Please see [LICENSE](LICENSE) for more information.

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance93

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity51

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

Unknown

Total

1

Last Release

47d ago

### Community

Maintainers

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

---

Top Contributors

[![amateescu](https://avatars.githubusercontent.com/u/246655?v=4)](https://github.com/amateescu "amateescu (2 commits)")

---

Tags

data-lineagephpprovprov-dmprov-jsonprovenancew3cw3c-provserializationW3CRDFprovenanceprovprov-dm

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/amateescu-prov/health.svg)

```
[![Health](https://phpackages.com/badges/amateescu-prov/health.svg)](https://phpackages.com/packages/amateescu-prov)
```

###  Alternatives

[opis/closure

A library that can be used to serialize closures (anonymous functions) and arbitrary data.

2.6k233.3M312](/packages/opis-closure)[jms/serializer

Library for (de-)serializing data of any complexity; supports XML, and JSON.

2.3k139.8M905](/packages/jms-serializer)[jms/serializer-bundle

Allows you to easily serialize, and deserialize data of any complexity

1.9k91.4M662](/packages/jms-serializer-bundle)[google/flatbuffers

FlatBuffers for PHP

26.0k144.0k5](/packages/google-flatbuffers)[apache/avro

Apache Avro™ is a data serialization system.

3.3k50.6k3](/packages/apache-avro)[flix-tech/avro-serde-php

A library to serialize and deserialize Avro records making use of the confluent schema registry

684.1M19](/packages/flix-tech-avro-serde-php)

PHPackages © 2026

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