Library / SDK
phar-io/manifest avatar
phar-io/manifest

phar-io/manifest: parsing and building PHAR manifest.xml in PHP

Component for reading phar.io manifest information from a PHP Archive (PHAR)

7,475 stars15 forksPHPNOASSERTION

At a glance

What is it?
phar-io/manifest reads and writes the manifest.xml that describes a PHP Archive, turning it into typed PHP objects. It is a small library for tooling authors, and its API is narrower than its name suggests.
Who is it for?
Adopt phar-io/manifest if you build or inspect PHAR archives in PHP and need the manifest as objects rather than raw XML, and install it with composer require phar-io/manifest. Do not adopt it if you need the archive contents, a signature check, or a way to edit an existing manifest in place; the README documents none of those.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 132 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem phar-io/manifest solves, and who actually hits it

A PHAR can carry a manifest.xml describing what the archive contains, who wrote it, under which licence, and what PHP version it needs. That file is plain XML. Reading it with SimpleXML gives you strings and no guarantee about structure. phar-io/manifest turns it into a tree of typed objects: ApplicationName, Version, Library, CopyrightInformation, AuthorCollection, License, RequirementCollection, BundledComponentCollection.

The audience is narrow and specific. If you write a packaging tool, a build script that stamps a manifest into an archive, or a verification step that inspects a third-party PHAR before you trust it, this library gives you a validated model instead of a DOM you have to defend against. If you only run PHARs and never author or inspect one, you have no reason to install it.

Note the scope: the description says reading manifest information from a PHP Archive. The library does not open the archive for you. You supply manifest.xml, either as a file path or as a string, and it parses that. Extraction, signatures, and stub handling are outside this package.

How the manifest model is built: loader, value objects, serializer

The data flow has three pieces. ManifestLoader::fromFile() reads a manifest.xml from disk and returns a Manifest object. The Manifest holds private properties for name, version, type, copyrightInformation, requirements, and bundledComponents. The serializer goes the other way: ManifestSerializer::serializeToString() takes a Manifest and emits XML in the https://phar.io/xml/manifest/1.0 namespace.

The types are not free-form. The example output shows an ApplicationName wrapping the string "some/library", a PharIo\Version\Version carrying major, minor, patch and a nullable preReleaseSuffix, and a Library object standing in for the type attribute. Requirements are a collection; in the sample it contains a PhpVersionRequirement holding a SpecificMajorAndMinorVersionConstraint with originalValue "7.0". Bundled components are a separate collection, empty in the sample.

That structure is the point. A version string is decomposed rather than passed around as text, and a constraint is a typed object rather than a substring comparison. The cost is verbosity: constructing a manifest by hand means nesting six or seven objects, as the README's API example shows. The repository ships manifest.xsd, so the schema the serializer targets is present in the tree and can be read directly rather than inferred from output.

Installing phar-io/manifest and reading a manifest.xml

Install it with Composer. The README gives two forms: a normal dependency, or a dev dependency if you only need it while running tests.

bash
composer require phar-io/manifest
composer require --dev phar-io/manifest

Then load a manifest from a file. The README's first example uses ManifestLoader::fromFile(), dumps the object, and prints the serialized form.

php
use PharIo\Manifest\ManifestLoader;
use PharIo\Manifest\ManifestSerializer;

$manifest = ManifestLoader::fromFile('manifest.xml');

var_dump($manifest);

echo (new ManifestSerializer)->serializeToString($manifest);

What you should see is a var_dump of a PharIo\Manifest\Manifest with six private properties, followed by XML in the phar.io 1.0 namespace. The README's sample output shows <contains name="some/library" version="1.0.0" type="library"/> and a <requires><php version="7.0"/></requires> block. If your input file lacks the expected namespace or a required element, the loader is the place where that surfaces, not the serializer.

The repository also carries examples/example-01.php and examples/example-02.php, which correspond to the two README walkthroughs. Reading those two files is faster than reconstructing the object graph from the dump.

Building a manifest through the API is verbose by design

The second README example constructs a Manifest from objects. You create a BundledComponentCollection, add a BundledComponent with a name and a Version, then pass an ApplicationName, a Version, a Library, a CopyrightInformation (itself holding an AuthorCollection and a License with a Url), a RequirementCollection, and the bundled collection.

php
$bundled = new \PharIo\Manifest\BundledComponentCollection();
$bundled->add(
    new \PharIo\Manifest\BundledComponent('vendor/packageA', new \PharIo\Version\Version('1.2.3-dev')
    )
);

$manifest = new PharIo\Manifest\Manifest(
    new PharIo\Manifest\ApplicationName('vendor/package'),
    new PharIo\Version\Version('1.0.0'),
    new PharIo\Manifest\Library(),
    new PharIo\Manifest\CopyrightInformation(
        new PharIo\Manifest\AuthorCollection(),
        new PharIo\Manifest\License(
            'BSD-3-Clause',
            new PharIo\Manifest\Url('https://spdx.org/licenses/BSD-3-Clause.html')
        )
    ),
    new PharIo\Manifest\RequirementCollection(),
    $bundled
);

Serializing that produces a <bundles> element with a <component name="vendor/packageA" version="1.2.3-dev"/> child, and a <requires><php version="*"/></requires> block because the RequirementCollection was empty. That last detail matters: an empty requirement collection does not omit the requires element, it produces a wildcard. If your build pipeline treats a wildcard PHP requirement as meaningful, you need to populate the collection deliberately.

What the library does not do, and where it is the wrong tool

It reads and writes manifest.xml. It does not open the PHAR. If you want to inspect the files inside an archive, verify a signature, or extract a stub, this package is the wrong layer and you want PHP's own Phar class or a different library.

There is no documented way to edit a manifest in place. The model is immutable-looking value objects plus a serializer, so a change is read, construct a new object graph, serialize. For a tool that bumps a version field in an existing manifest, that means rebuilding the whole Manifest from parsed parts, and the README does not show a round-trip example that starts from a loaded manifest and modifies one field.

The README also does not document rollback, error types, or what happens when the XML is well-formed but violates the schema. Validation behaviour has to be read out of src/ and manifest.xsd, not the README. Treat that as a real gap if you are wiring this into a release pipeline where a malformed manifest should fail loudly with a specific exception you can catch.

Finally, the version constraint model is limited to what the sample shows: a specific major and minor pair. If you need ranges, exclusions, or caret semantics in a requirement, confirm the constraint classes in src/ support it before designing around this library.

phar-io/manifest compared with parsing the XML yourself

The obvious alternative is SimpleXML or DOMDocument plus a few XPath queries. That approach has no dependency beyond the PHP extensions you already have, and for a one-off script that pulls a single name attribute out of <contains>, it is less code than constructing the object graph.

The difference is what happens when the input is wrong or unusual. With raw XML you own every check: is the namespace right, is the version parseable, is the licence element present. phar-io/manifest centralises those decisions in typed classes, and the serializer guarantees the output shape. If your project already depends on phar-io/version, the version objects here are the same ones you are using elsewhere, which keeps version handling consistent across a build tool.

There is a second alternative worth naming: not reading the manifest at all and relying on Composer metadata instead. For most PHP distribution decisions that is sufficient, and it sidesteps PHAR-specific XML entirely. The manifest format earns its place when the artefact itself has to carry its own description, which is the case phar.io exists to serve.

Maintenance, licence and the cost of upgrading

The last push to the default branch was on 2026-05-20. The most recent release is 2.0.4 from 2024-03-03, preceded by 2.0.3 and 2.0.2, both from 2021-07-20. That release cadence is slow and the 2.0.x line has been stable for a long time, so an upgrade is unlikely to be a recurring chore. Expect to pin a 2.0.x version and leave it.

The release notes for 2.0.4 are not reproduced here, so what changed between 2.0.3 and 2.0.4 is not something this article can state. If you are upgrading across those two, read CHANGELOG.md in the repository rather than guessing from the version number.

On licensing: the repository metadata reports NOASSERTION, which means the licence could not be identified automatically. The LICENSE file is present at the top level and the README's own example manifest uses BSD-3-Clause, but that is example data inside a sample, not a statement about this package's licence. Read LICENSE before you ship it inside a distributed archive. This is not legal advice, and the discrepancy between the metadata and the file is exactly the kind of thing to resolve by reading the file.

Editorial conclusion

Adopt phar-io/manifest if you build or inspect PHAR archives in PHP and need the manifest as objects rather than raw XML, and install it with composer require phar-io/manifest. Do not adopt it if you need the archive contents, a signature check, or a way to edit an existing manifest in place; the README documents none of those. Before relying on it, verify that the manifest you need to read uses the https://phar.io/xml/manifest/1.0 namespace and check manifest.xsd in the repository for the schema it validates against.

Frequently asked questions

What is phar-io/manifest used for?

It reads and serializes the manifest.xml that describes a PHP Archive, exposing fields such as the application name, version, type, copyright, requirements and bundled components as typed PHP objects. It does not open or extract the PHAR itself.

How do I install phar-io/manifest?

Add it with Composer using composer require phar-io/manifest, or composer require --dev phar-io/manifest if you only need it during development, for example to run a test suite.

Can phar-io/manifest read the files inside a PHAR archive?

No. The library parses manifest.xml, either from a file path or as XML content, and serializes it back. Archive extraction, signatures and stubs are outside its scope according to the README.

What XML namespace does the serialized manifest use?

The README's output examples show the root element in the https://phar.io/xml/manifest/1.0 namespace, with contains, copyright, requires and bundles elements beneath it.

Official sources

  1. Issues
  2. phar-io/manifest on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/phar-io-manifest.svg)](https://hysenlabs.com/projects/phar-io-manifest)