# phar-io/version: parsing version constraints in PHP

> A small PHP library that parses SemVer-style constraints such as ^7.0 and ~1.1.0 and tests discrete versions against them. It is a building block for tooling, not a version manager, and its README is thin on error handling.

**phar-io/version** — Library for handling version information and constraints

- Repository: https://github.com/phar-io/version
- Website: https://phar.io/
- Stars: 7,465 · Forks: 18
- Language: PHP
- License: BSD-3-Clause
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/phar-io-version

## What phar-io/version actually decides

The library answers one narrow question: given a constraint string and a concrete version, does the version fall inside the range the constraint describes? The README frames it as a constraint describing "a range of versions or a discrete version number", with version numbers following the semantic versioning schema of `<major>.<minor>.<patch>`. That is the whole surface area. It is aimed at authors of PHP tooling: build scripts, PHAR packaging pipelines, release checkers, or any code that has to interpret a constraint a user typed rather than one a resolver produced.

The scope matters because the name invites a wrong expectation. This is not a version manager, not a dependency resolver, and not a lockfile format. It parses and compares. If your problem is "which of these twenty packages can be installed together", this library gives you one of the primitives, not the answer. The phar.io project uses it in that primitive role, and the repository layout reflects it: a src/ directory, a tests/ directory, and nothing that looks like a solver.

## How the parser and the operators work

Two classes carry the work. VersionConstraintParser is constructed with no arguments, and its parse() method takes a constraint string and returns a constraint object. That object exposes complies(), which accepts a Version and returns a boolean. The data flow is string in, object out, version in, boolean out. There is no state to manage and no configuration file.

The operators are where the library earns its place. Standard mathematical operators such as `<=` and `>=` are supported, plus two special ones. The caret operator `^1.0` is defined as equivalent to `>=1.0.0 <2.0.0`, meaning every version within major version 1. The tilde operator is subtler: `~1.0.0` expands to `>=1.0.0 <1.1.0`, every version within minor version 1.1, but the README states that the behavior depends on whether a patch level is provided. With no patch level, tilde behaves like caret, so `~1.0` is identical to `^1.0`. That asymmetry is the kind of detail people get wrong when they write comparisons by hand.

Pre-release handling arrived in version 2.0.0. The README gives the example of `3.0.0-alpha.1` and `3.0.0-alpha.2`, where the second is greater than the first. Pre-release labels are therefore ordered rather than ignored, which matters if your constraints ever meet a tag like `1.0.0-beta`.

## Installing phar-io/version and checking your first constraint

The README gives Composer as the installation route, as a per-project dependency. Run this from your project root:

```bash
composer require phar-io/version
```

Composer resolves the package and writes it to composer.json and the lockfile. If the library is only needed for your test suite, the README offers the development-time variant, which keeps it out of production installs:

```bash
composer require --dev phar-io/version
```

With the package installed, the README's usage example is the shortest path to a working check. It parses `^7.0`, then tests three versions against it:

```php
use PharIo\Version\Version;
use PharIo\Version\VersionConstraintParser;

$parser = new VersionConstraintParser();
$caret_constraint = $parser->parse( '^7.0' );

$caret_constraint->complies( new Version( '7.0.17' ) ); // true
$caret_constraint->complies( new Version( '7.1.0' ) ); // true
$caret_constraint->complies( new Version( '6.4.34' ) ); // false
```

You should see the three booleans the comments claim. The `6.4.34` case is the useful one to run first, because it confirms that the caret expansion is actually bounding the range rather than doing a loose string comparison. Swap in the tilde example from the README (`~1.1.0` against `1.1.4` and `1.2.0`) to see the narrower minor-level bound.

## Where the documentation stops short

The README is a usage sketch, not a reference. It documents the happy path and the two special operators, and then stops. It does not document what the parser does with a malformed constraint string, whether an exception is thrown, which exception type, or whether some inputs are silently accepted. Anyone wiring this into a tool that accepts constraint strings from users or from a config file will hit that gap, because user input is exactly where malformed constraints come from.

The README also does not document rollback or downgrade behavior, and there is no statement about backwards compatibility guarantees across major versions. The changelog exists as a top-level file, so the information may be there, but the README does not point at it. The practical consequence is that you should treat the parser boundary as something to test yourself rather than something to trust from the docs.

A second constraint is timing. The most recent release listed is 3.2.1 from 2022-02-21, while the last push to the repository was on 2026-05-20. That pattern, recent commits with no matching tagged release, suggests work that has not been cut into a version. It does not tell you what changed. If you depend on the library, pin the version you tested rather than tracking the branch.

## phar-io/version compared with Composer's own constraint handling

The obvious alternative is Composer itself. Composer parses the same constraint syntax, including caret and tilde, and it does so as part of a full dependency resolution pass with transitive requirements, platform checks, and lockfile generation. The difference is not accuracy, it is scope. Composer answers "what set of packages satisfies all these constraints together". phar-io/version answers "does this one version satisfy this one constraint".

That makes the choice straightforward. If you are writing a Composer plugin or anything that needs resolution, you want Composer's machinery, not this. If you are writing a standalone tool that reads a constraint from somewhere and needs a yes-or-no answer without pulling in the resolver, phar-io/version is the smaller dependency. The trade-off is that you get no transitive reasoning, no conflict detection, and no explanation of why a constraint failed beyond the boolean. The library also gives you no parsing of Composer's `||` alternative syntax or stability flags, at least not anywhere the README describes. If your constraint strings come from composer.json, check that assumption before adopting.

## Licence, maintenance and upgrade cost

The package is licensed BSD-3-Clause. That is a permissive licence, and it is compatible with use in closed-source PHP projects in the usual way, but the repository's LICENSE file is the authority on the terms and this article is not legal advice. The practical implication for most teams is that BSD-3-Clause imposes fewer obligations than a copyleft licence would, and the main requirement is retaining the copyright notice and licence text.

Upgrade cost is low by construction. The public surface described in the README is two classes and a handful of methods, and the constraint semantics are fixed by the semantic versioning rules the library implements. A major version bump is the only place where behaviour could shift, and the README does not promise anything about that. The version history shows a gap: 3.1.0 in 2021, 3.1.1 and 3.2.1 in early 2022, and nothing tagged since. For a library this small, a stable API with few releases is normal rather than alarming, but it does mean you should read the changelog before moving between major versions instead of assuming a smooth path.

## Conclusion

Adopt phar-io/version if you are writing PHP tooling that must decide whether a concrete version satisfies a constraint string, and you want the caret and tilde semantics handled for you instead of hand-rolling comparisons. Do not adopt it if you need a dependency resolver, a lockfile, or any transitive constraint solving; Composer already owns that job, and this library is the lower-level piece. Before committing, verify how your input reaches the parser: the README shows the happy path for ^7.0 and ~1.1.0 but does not document what happens on malformed constraint strings, so test that path against your own inputs first.

## FAQ

### What is phar-io/version used for in PHP?

It parses a version constraint string such as ^7.0 or ~1.1.0 and checks whether a concrete version satisfies it. The README describes it as a library for handling version information and constraints, with the constraint describing a range of versions or a discrete version number.

### How do I install phar-io/version?

Add it as a per-project dependency with Composer using composer require phar-io/version. If you only need it during development, the README gives composer require --dev phar-io/version instead.

### What is the difference between the caret and tilde operators in phar-io/version?

The README defines ^1.0 as equivalent to >=1.0.0 <2.0.0, covering every version within major version 1. The tilde operator ~1.0.0 expands to >=1.0.0 <1.1.0, but with no patch level provided it behaves like the caret operator, so ~1.0 is identical to ^1.0.

### Does phar-io/version handle pre-release versions?

Yes, as of version 2.0.0. The README states that pre-release labels are supported and taken into account when comparing versions, and gives the example that 3.0.0-alpha.2 is greater than 3.0.0-alpha.1.

### What happens if phar-io/version is given an invalid constraint string?

The README does not document this case. It shows parsing of ^7.0 and ~1.1.0 only, and does not state whether a malformed constraint throws an exception or is handled some other way, so test your own inputs against the parser.

## Sources

- [License: BSD-3-Clause](https://github.com/phar-io/version/blob/master/LICENSE)
- [phar-io/version on GitHub](https://github.com/phar-io/version)
- [Project website](https://phar.io/)
- [README](https://github.com/phar-io/version/blob/master/README.md)
- [Releases](https://github.com/phar-io/version/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/phar-io-version
