Download the PHP package meraki/http-router without Composer

On this page you can find all versions of the php package meraki/http-router. 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 http-router

http-router

Maps HTTP requests to HTTP responses in PHP 8.4+.

Features

Routing model

HTTP methods

Parameters (via the Caster system)

Status semantics

Extensibility

Roadmap

What's coming after alpha, grouped roughly by theme:

Content negotiation (planned for the negotiation milestone)

Observability

Performance

Routing extras

Tooling

Runtime

Installation

Usage

Instantiate the router, pass the request method and request target, then handle the result.

route() deliberately takes the method and request target as strings, not a request object, so the router doesn't depend on any particular HTTP framework. To support content negotiation later, a small request-context object may be added.

See examples README catalogues each URL with what it demonstrates.

Intentions and design decisions

  1. A nested RESTful child needs a parent handler that can address it. The child inherits the matched parent's signature.

    At each non-terminal namespace level in the URL, the router needs some handler whose signature consumes the local args — that handler defines the parameter chain the nested child inherits. By default the router tries the request method first; if that finds nothing, it falls back to the methods in Config::$addressingFallbackMethods (defaults to ['get'] — GET /resource/{id} is the canonical REST way to address an item). The matched parent is used only for signature inheritance and is never invoked — only the deepest (primary) match is dispatched.

    For example, this request:

    resolves to Project\Http\Persons\Dependents\PostAllAction(string $id) as long as Project\Http\Persons\GetOneAction(string $id) exists to address the person — you don't need to define a phantom Project\Http\Persons\PostOneAction (which would be semantically wrong; POST /persons/{id} has no natural REST meaning).

    If you want the stricter pre-feature behaviour (parent must match the request method exactly), clear the fallback list: Config::create($ns)->withAddressingFallbackMethods().

    (This applies to RESTful types only — Action routes are standalone; see decision 5.)

  2. No PSR-7 dependency. The library does not rely on PSR-7 for request/response objects, for the greatest compatibility between HTTP implementations.

  3. Convention over configuration. The URL structure and HTTP method imply the handler's fully-qualified class name and method signature. There are no route files and no attributes on handlers — both of which are more error-prone and less performant.

  4. The class name encodes intent — there is no inflection, pluralization, or URL guessing. The class-name suffix alone determines the route type (GetAllAction → Collection, GetOneAction → Item, GetAction → Action). A compound resource like RegisteredBusinesses needs no special inflection rule. Because the mapping is mechanical and total, handler names are deterministic and reversible (a prerequisite for future reverse-routing).

  5. Action (static) routes are standalone and take priority. An Action route binds only the segments that follow its own namespace; it never inherits a parent's arguments, and it wins over a RESTful handler at the same namespace. This makes its URL fully deterministic. Reach for it for verbs or fixed overrides — e.g. a static /users/create living alongside a dynamic /users/{id}, or a vanity /users/{username}. (See examples/Http/Music/TrackInfo/GetAction.php for the ambiguity that mixing static and RESTful routing can create.)

  6. string is the universal segment type; only narrowing types can fail. A string parameter accepts any URL segment and never produces a 422. Only narrowing types (int, float, enums, value-objects) can reject a value as unprocessable.

  7. HTTP methods are handled deliberately. CONNECT and TRACE are never application methods (always 405). OPTIONS is auto-synthesised (204) advertising the allowed methods, and HEAD is derived from GET. The supported-method set is configurable via Config::withAdditionalMethods() for WebDAV (PROPFIND, MKCOL, …) or other extensions.

  8. Method discovery is "poisoning-proof." When building the Allow list for a 405/OPTIONS, a single misconfigured handler for one method does not hide the other valid methods available at the same URL.

  9. Misconfigurations surface as exceptions, not silent mis-routes. A variadic parent that would permanently shadow a child route throws UnallowedVariadicParameter; an unreachable nested RESTful handler throws SignatureMismatch. These are developer errors in the handler tree, so they are raised rather than quietly returning a 404.

  10. Status codes are precise. 400 = the URL is too short for a required parameter (structurally malformed); 404 = no route of that shape (including too many segments); 422 = a route matched but a value can't cast to its parameter's type.

  11. URLs are matched case-insensitively. The whole request target is lower-cased before matching, so /Users/1 and /users/1 resolve to the same handler. The lower-cased segment is also what reaches the caster, so a pure (unbacked) enum's case-name match (e.g. Month::August) is intentionally case-insensitive. Use lower-case for string-backed enum values and URL-friendly value-object inputs; if you need original case preserved in a bound value, type the parameter as string (universal) rather than relying on case for matching.

How routing works

Take $router->route('GET', '/states/qld/suburbs/emerald'):

  1. Normalise. The method is lower-cased and the request target is parsed and split into segments — ['states', 'qld', 'suburbs', 'emerald']. An empty path (/ or "") targets the root resource (rootPathSubNamespace, default Home).

  2. Check the method. If it isn't in the supported set, short-circuit to 405 (or 404 if the URL has no handlers at all).

  3. Walk the segments, left to right. For each segment the router tries to extend the current namespace by appending the class-name form of the segment. If an action class exists at that extended namespace, the segment is a namespace component and begins a new level; otherwise it is an argument collected against the current level:

    segment extends to role
    states States namespace
    qld States\Qld? (none) argument of the States level
    suburbs States\Suburbs namespace
    emerald States\Suburbs\Emerald? (none) argument of the States\Suburbs level
  4. Match a handler at each level. Candidate class suffixes are tried in priority order — Action → Collection (AllAction) → Item (OneAction) — and the first whose signature fits the bound arguments wins. Trying Action first is what lets /persons/schema resolve to Persons\Schema\GetAction even when Persons\Schema\GetOneAction also exists.

  5. Resolve the arguments — in this order:

    1. Inherited first (RESTful only). A Collection/Item child starts with the parameters and bound arguments inherited from its matched parent (qld flows down to States\Suburbs\GetOneAction). An Action route inherits nothing.
    2. Then local segments. The level's own segments fill the remaining parameters, left to right. Each segment is cast to the parameter's declared type; if no declared type accepts it, the candidate becomes a 422 candidate.
    3. Then the variadic. Any leftover segments must be absorbed by a trailing variadic parameter (...$args); if there's no variadic, the candidate doesn't fit.

    So /states/qld/suburbs/emerald binds ['qld', 'emerald'] to States\Suburbs\GetOneAction(string $state, string $suburb) — qld inherited from the parent, emerald from the local segment.

  6. Build the result. A matched chain becomes a 200 carrying the primary (deepest) handler and its bound arguments. A failure becomes 400 / 404 / 422; method discovery produces 405 or an auto-synthesised 204 for OPTIONS.

Route types and their intentions

Type Class suffix Intent Inherits parent args?
Collection GetAllAction Operate on a whole collection (list, create-into). Yes
Item GetOneAction Operate on a single addressed member of a collection; consumes the id segment. Yes
Action GetAction A verb / static / vanity route that bypasses RESTful semantics. Binds only its own trailing segments and wins over RESTful handlers at the same namespace. No

Collection and Item are the RESTful types: they model resources and chain together (/states/{state}/suburbs/{suburb}), each inheriting its parent's identifying arguments. Action is the escape hatch: a fixed route that behaves "as if the file existed at that path," for cases the RESTful conventions shouldn't own.

Contributing

See CONTRIBUTING.md.


All versions of http-router with dependencies

PHP Build Version
Package Version
Requires php Version ^8.4
willdurand/negotiation Version ^3.1
psr/log Version ^3.0
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 meraki/http-router contains the following files

Loading the files please wait ...