Download the PHP package bentools/url-pattern without Composer

On this page you can find all versions of the php package bentools/url-pattern. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package url-pattern

UrlPattern

CI Workflow Coverage License Total Downloads

A PHP implementation of the WHATWG URL Pattern Standard (the URLPattern web API), validated against the official web-platform-tests suite.

WPT conformance: 369/369 cases of urlpatterntestdata.json pass on PHP 8.3, 8.4 and 8.5, with no skipped case.

Installation

Requirements: PHP >= 8.3 with ctype and mbstring, and PCRE2 >= 10.40 (for \p{ID_Start}; always true with the PCRE2 bundled with PHP, check it only if PHP is linked against a system library). intl is recommended on PHP < 8.5 (faster IDNA).

Usage

Creating a pattern

An invalid pattern throws BenTools\UrlPattern\Exception\InvalidPatternException (the equivalent of the JavaScript TypeError).

The normalized component patterns are exposed as read-only properties:

Matching

test() and exec() accept a URL string (with an optional base URL) or an array of component values. They never throw on an invalid URL: they return false / null. The only exception is a programming error: passing a base URL along with an array input throws an InvalidArgumentException.

URLPatternResult exposes inputs, plus one URLPatternComponentResult (input, groups) per component: protocol, username, password, hostname, port, pathname, search, hash. A group that did not participate in the match is null (undefined in JavaScript). Anonymous groups are numbered from 0, and, PHP being PHP, their keys are integers.

Options

Option Type Default Description
ignoreCase bool false Case-insensitive matching (pathname, search and hash, as in the spec)
backtrackLimit int (>= 1) 100_000 Maximum PCRE work per component match, see Security

An invalid option value throws an InvalidPatternException.

Performance

Patterns are compiled once, in the constructor. URLPattern instances are immutable (readonly) and can be shared and cached freely. There is no global cache in the library: if you build patterns from user input, keep an LRU cache of compiled instances on your side.

Indicative figures (Apple Silicon, https://example.com/books/:id):

PHP URL parser new URLPattern() test() (match) test('foo')
8.3 rowbot/url (via polyfill) ~630 µs ~75 µs ~6 µs
8.4 rowbot/url (via polyfill) ~500 µs ~90 µs ~9 µs
8.5 native Uri\WhatWg\Url (lexbor) ~155 µs ~4 µs ~0.2 µs

Matching a URL string is dominated by URL parsing: on PHP < 8.5, matching against an array of components (which skips the parser), or upgrading to PHP 8.5, is much faster.

URL parser

The encoding callbacks of the specification rely on the WHATWG URL parser. This library uses Uri\WhatWg\Url, which is native since PHP 8.5, and backported to PHP 8.3/8.4 by league/uri-polyfill (itself built on rowbot/url). On PHP 8.5, the polyfill is inert and the native implementation is used.

Why league/uri-polyfill rather than rowbot/url directly: a single API (Uri\WhatWg\Url) across versions, and the native, much faster parser on PHP 8.5, while the polyfill still delegates to rowbot/url, a WPT-compliant parser, on older versions. PSR-7 / RFC 3986 URI libraries are not suitable: URL patterns require WHATWG semantics (IDNA, IPv4 normalization, backslashes, special schemes...).

Uri\WhatWg\Url does not expose the "state override" entry points of the URL parser that the encoding callbacks use, so the corresponding parser states (port, path, opaque path, query, fragment, userinfo encoding) are reimplemented in Internal\Canonicalizer; the URL parser is used for scheme validation and host parsing.

The native parser of PHP 8.5.1 deviates from the URL standard in two places, which the library normalizes itself:

Differences with the specification

The specification compiles patterns into ECMAScript regular expressions (with the v flag). PHP has no ECMAScript regex engine, so the generated expressions are translated to PCRE2 (/u). The translator validates the ECMAScript syntax (it rejects what a JavaScript engine rejects, e.g. \m, (?R) or \H, which PCRE would accept) and preserves the ECMAScript semantics where PCRE differs:

Topic Behavior
. Translated to "any code point but \n, \r, U+2028, U+2029", like JavaScript (or any code point under (?s:)).
\s, \S Translated to the ECMAScript white space + line terminator set.
\d, \w, \b ASCII, like JavaScript in Unicode mode. With ignoreCase, JavaScript's \w also matches U+017F and U+212A; PCRE does not.
v-flag set operations ([A--B], [A&&B], nested classes) Supported, translated with lookaheads.
\q{...} string disjunctions Supported in class unions; in negated classes, only single-code-point strings are accepted (like JavaScript); rejected in intersections and subtractions.
Properties of strings (\p{RGI_Emoji}...) Not supported: InvalidPatternException.
\p{...} names Passed to PCRE2, which matches property names loosely: some names JavaScript rejects (e.g. different casing) are accepted.
Lookbehind PCRE2 requires a bounded length (variable-length lookbehind needs PCRE2 >= 10.43, i.e. a recent PHP).
Backreferences (\1, \k<name>) Not supported (rejected by the ReDoS guard).
Lone surrogates in regexps (\uD800) Not supported: PHP strings are UTF-8 and cannot contain them.
Duplicate named groups in different alternatives (ES2025) Rejected.
ReDoS guard Some valid patterns are rejected, see below.
Backtracking limit A match exceeding the limit is reported as no match.

Other notes:

Security (ReDoS)

URL patterns may come from untrusted sources (e.g. Mercure subscribers), and a malicious regular expression can make a backtracking engine run for ages, freezing a single-threaded event loop. The library defends in depth:

  1. Linear-time guard (at construction): user-provided regexp groups whose structure is prone to catastrophic backtracking are rejected with an InvalidPatternException. That is a repeated sub-expression (*, +, {n,}, {n,m} with m > 1, or a URLPattern */+ modifier) containing an unbounded quantifier, e.g. (a+)+, (?:a*)*, ((a+)){2,}. Backreferences are rejected too. This is a deliberate deviation from the specification. It is a heuristic, not a proof of linearity, hence the next layer.
  2. Bounded matching (at match time): every test()/exec() call temporarily sets pcre.backtrack_limit (PCRE2's match limit) to the backtrackLimit option, and restores the previous value afterwards. The limit applies to each component match: with the default of 100,000, a hostile component costs about a millisecond with the PCRE JIT, and a whole call at most 8 times that. The limit is also enforced by the JIT, which therefore stays enabled. Without the JIT (pcre.jit=0, or a platform refusing executable memory), each unit of the limit is far more expensive: a hostile component can cost about half a second with the default limit, so lower backtrackLimit accordingly (e.g. 10,000) or keep the JIT enabled. Note that patterns without any regexp group can be polynomial or even exponential too (e.g. *a*a*a*b, or /x:a+, which behaves like (a+)+); this layer covers them.
  3. Fail as no match: any PCRE error (limit exhausted, JIT stack limit, ...) results in false / null, never in an exception or a warning.

If ini_set() is disabled on your platform, the process-wide pcre.backtrack_limit applies instead (PHP's default is 1,000,000).

Recommendations for untrusted patterns:

Development

The WPT fixtures are vendored in tests/Fixtures.

License

MIT.


All versions of url-pattern with dependencies

PHP Build Version
Package Version
Requires php Version >=8.3
ext-ctype Version *
ext-mbstring Version *
league/uri-polyfill Version ^7.8
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package bentools/url-pattern contains the following files

Loading the files please wait ...