league/uri: parsing, building and expanding URIs in PHP
[READ-ONLY] URI manipulation Library
At a glance
- What is it?
- The League URI package gives PHP simple and intuitive classes for managing URIs, with a dedicated class for each flavour of identifier, from the generic Uri through Http, Ftp, Ws, Urn and URN-style schemes, plus URI templates and URL patterns. The requirements are the part to read carefully, because an internationalised host or an IPv4 conversion can throw an exception unless the right extension is present.
- Who is it for?
- Adopt league/uri when your PHP application parses, builds or expands URIs as a first-class concern, especially if you handle internationalised hosts or need RFC 6570 templates, and pin the version you depend on. Do not adopt it as a replacement for a full HTTP client, since it manipulates identifiers and does not make requests, and do not adopt it in an environment that cannot install the intl, dom or GMP extensions it documents.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 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 November 7, 2026, and from our analysis. They are not legal advice.
Star history
- thephpleague/uri1,132 ★ · +1
| Repository | 2026-10-22 | 2026-11-07 |
|---|---|---|
| thephpleague/uri | 1.1k | 1.1k |
1 Stars in the last 16 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
A sub-split, and a warning to read it first
The repository description marks the project as a read-only URI manipulation library, and the README carries a warning that this is a sub-split. For development, pull requests and issues, the place to go is the uri-src repository.
That warning is the first thing to know, because it changes where the work happens. The split pattern separates the repository that is packaged and versioned from the repository where the source is edited, and a contributor who opens a pull request in the wrong place will be turned away.
The library itself is described as providing simple and intuitive classes to manage URIs in PHP, and that is the whole scope. It is a manipulation layer: it parses a URI into components, it builds one, it resolves relative references against a base, and it expands templates into concrete URIs. It does not make HTTP requests and it is not a client library.
The package installs with Composer:
composer require league/uriIt is MIT licensed, and the README links the MIT license file, a packagist download badge and the release badge, so the project follows the usual pattern of a well-established open source library with a public documentation site and a conventional release train.
The extension requirements are the real gotcha
The system requirements section is short and every line of it is a possible runtime exception, which is unusual to see spelled out so plainly in a PHP package.
You require PHP 8.1 or newer, and the latest stable version is recommended. Handling of an IDN host requires the presence of the intl extension, or a polyfill for the intl IDN functions such as symfony/polyfill-intl-idn, otherwise an exception is thrown when attempting to validate or interact with such a host.
IPv4 conversion requires at least one of the GMP extension, the BCMatch extension, or a 64-bit PHP version, otherwise an exception is thrown when attempting to convert a host as an IPv4 address.
Parsing or generating HTML related content requires the dom extension.
Three requirements and three failure modes is a fair ratio, and the failure mode is always an exception at the moment of use rather than a check at install time. For a library whose job is to handle whatever a user types into a URL field, that matters. The IDN case in particular is easy to overlook in an application that never handles internationalised domains, and the failure arrives the first time a user pastes one.
The IPv4 requirement is a little different, since it is about arithmetic on large numbers rather than about a missing feature. GMP, BCMatch or a 64-bit build, and the choice is a property of the deployment rather than of the code.
One class per flavour of identifier
The root of the repository is a list of classes, and the list is the fastest way to understand the design.
There is Uri.php for the general case, with BaseUri.php underneath it, and SchemeType.php, TypeConverter.php and UriScheme.php handling the scheme and the conversion of components between types. UriInfo.php and UriResolver.php deal with the metadata about a URI and with resolving a reference against a base. Builder.php is the fluent construction path.
Then there are the specific schemes, each in its own file, with matching test files. Http.php and HttpFactory.php cover HTTP, UriTemplate.php and the UriTemplate/ directory cover template expansion, UrlPattern.php with UrlPattern/ and UrlPatternBuilder.php cover the newer pattern syntax, and Urn.php covers uniform resource names. FtpTest.php, WsTest.php and DataTest.php in the same pattern show that the test suite covers the same ground.
The naming convention, one class and one test per scheme, tells you the shape of the library. It is not a single Uri class with a scheme string, it is a family of small classes, and the family is what makes the type system able to say that an Http object is an Http object.
There is also a performance angle, visible in the file names. HttpBench.php and UriBench.php are benchmarks sitting next to the source, and a library that keeps benchmarks in the repository is a library that expects to be measured.
Templates, patterns and the RFCs behind them
The topics attached to the repository name the standards the library implements, and they are worth reading as a feature list.
There is rfc-3986, which is the generic URI syntax, rfc-3987, which is the IRIs used for internationalised identifiers, and rfc-6570, which is URI templates, the syntax where a template such as a path with a brace expression expands into concrete URIs. There is uri-template and uri-parser and uri-extraction as separate concerns, which suggests the library separates building a template from expanding one and from pulling a URI out of free text.
The class list backs that up. UriTemplate.php with its own directory is the RFC 6570 implementation, and UrlPattern.php with UrlPatternBuilder.php is a separate, newer pattern mechanism with a builder of its own. The link list in the README also points at Guzzle 6's UriTemplate implementation, which is the sort of reference a library like this cites.
For a developer, the practical question is which of these you need. A template is the right tool when you are building links to a REST API and want the expansion rules handled for you. A URL pattern is the right tool when the shape of a URL is a pattern you want to match against as well as generate. Having both in one library, with different class names, is the kind of thing that saves a project from maintaining two URL helpers.
PSR-7 and the interfaces split
The dependencies are listed as two items, and both are about interoperability rather than about functionality. The first is the League URI Interfaces, and the second is PSR-7.
PSR-7 is the PHP-FIG interface standard for HTTP messages, which includes the URI value object, and the repository contains a Psr7IntegrationTest.php, so the integration between the two is something the project tests rather than something it assumes.
The interfaces package is a separate repository, which is the pattern this ecosystem uses: the interfaces describe the contract, the implementation lives in the main package, and an application can type against the interface and swap the implementation. For a library whose objects are passed around in application code, that separation is what stops a dependency on the concrete package from spreading.
The composer.json at the root is the other half of the picture, since it is what declares the PHP version, the extensions and the two dependencies, and it is the file a package manager reads before anything is installed.
Where league/uri is the wrong choice
The first wrong-tool case is an application that needs to make requests. This library manipulates URI objects. If the requirement is an HTTP client that follows redirects, manages cookies and pools connections, the answer is a client library, and the URI handling inside it is one component rather than the product.
The second is a project that only needs to split a URL into parts. PHP has parse_url in the standard library, and the built-in function covers the common case of taking a string apart. The reason to reach for league/uri is that you also want to build one, validate it, resolve references, expand templates or convert between representations, and the more you need, the more the wrapper earns its place.
The third is an environment without the extensions the library documents. The intl, dom and GMP requirements are not exotic, but a hosting platform that pins an old PHP build with a minimal extension set will fail at runtime rather than at install, and the exception messages are clear but late. A container image with the extensions present removes the problem entirely, and for a team that deploys to shared hosting it is a real constraint.
The fourth is a codebase that treats URLs as strings throughout. Adopting an object model for URIs means changing call sites, and the value only shows up if the rest of the application starts passing URI objects around.
MIT, version 7.8, and a mature release train
The project is MIT licensed, with the LICENSE file at the root, and the current version is 7.8.1, released in March 2026, after 7.8.0 in January 2026 and 7.7.0 in December 2025. The default branch is master, the repository is not archived, and the last push was on 2026-10-15.
A version 7 with regular minor releases and a changelog is the profile of a library that has been depended on for a long time, which is also what the split-repository arrangement implies. This is not a new package, it is a mature one that has been refactored into interfaces and a sub-split, and the CHANGELOG.md at the root is the document to read when an upgrade note matters.
The documentation lives at uri.thephpleague.com rather than in the repository, and the repository itself is mostly source and test files, which is what you want from a package that is installed rather than read.
For an adopter, the practical checks are short. Confirm the PHP version, confirm the extensions you need, and confirm the version you pin is one you have read the changelog for, because a library with this release cadence will have changed something between the version you remember and the one you install.
Editorial conclusion
Adopt league/uri when your PHP application parses, builds or expands URIs as a first-class concern, especially if you handle internationalised hosts or need RFC 6570 templates, and pin the version you depend on. Do not adopt it as a replacement for a full HTTP client, since it manipulates identifiers and does not make requests, and do not adopt it in an environment that cannot install the intl, dom or GMP extensions it documents. Before you commit, check the extension requirements against your production PHP build, since a missing intl extension turns an IDN host into an exception at runtime rather than at install time.
Frequently asked questions
What does the league/uri package do?
It provides simple and intuitive classes to manage URIs in PHP, with a class per identifier flavour, Uri for the general case plus Http, Urn, UriTemplate and UrlPattern, along with a builder, a resolver and a type converter. It manipulates identifiers rather than making requests.
How do I install league/uri?
With composer require league/uri. The package requires PHP 8.1 or newer, with the latest stable version recommended, and its dependencies are the League URI interfaces and PSR-7.
What extensions does league/uri need?
Handling an IDN host requires the intl extension or a polyfill such as symfony/polyfill-intl-idn, otherwise an exception is thrown when validating such a host. IPv4 conversion requires GMP, BCMatch or a 64-bit PHP version. Parsing or generating HTML related content requires the dom extension.
Where do I report issues for league/uri?
Not here. The README states that this repository is a sub-split and that for development, pull requests and issues you should visit the uri-src repository. The package itself is installed from Packagist as league/uri, and the documentation is at uri.thephpleague.com.
What licence is league/uri released under?
The MIT License, with the license file in the repository root. The most recent listed version is 7.8.1 from 2026-03-15, following 7.8.0 in January 2026 and 7.7.0 in December 2025, and the last push was on 2026-10-15.
Official sources
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.
[](https://hysenlabs.com/projects/thephpleague-uri)Star history chart for your README
[](https://hysenlabs.com/projects/thephpleague-uri)Was this useful?