Download the PHP package rammewerk/router without Composer

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

Rammewerk Router

Rammewerk Router is a lightweight, high-performance PHP router designed for modern applications. It prioritizes fast route resolution, minimal overhead, and a straightforward setup. Built for PHP 8.4, it takes a modern, class-based approach while remaining flexible and powerful in its minimalism.

With minimal configuration required, Rammewerk Router is easy to set up while still offering a wide range of features like type-safe parameters, dependency injection, and middleware. It provides just the right amount of structure without unnecessary complexity - delivering performance and flexibility in a simple, intuitive package.

Key Features:

Table of Contents

🎯 Project Goals

These goals reflect what Rammewerk strives to achieve across all its components:

By using Rammewerk, you get a minimal yet powerful foundation that’s easy to build on and improve. Let’s dive in! 🔧✨

🚀 Getting Started

Install

Install Rammewerk Router via composer:

Requirements

Usage

🧭 Basic Routing

While the Rammewerk Router is designed for class-based routing, it also supports closures.

Here’s a simple example:

This matches /hello, triggers the closure, and returns “Hello World!”

🏗️ Class-based Routing

Class-based routing is the core feature of Rammewerk Router. It maps paths and their nested routes directly to a class, making it both powerful and flexible.

Here’s how it works:

With this setup, the ProfileRoute class will handle all requests to /profile (and its sub-paths, unless overridden by other routes).

Here’s an example of a simple class for the /profile path:

The index() method is the default handler for the base path of a class-based route. In this case, accessing /profile triggers the index() method.

You can also define class routes with a single __invoke() method. This will be called if no other method matches or is defined. The __invoke() method is best used when the class doesn’t have additional route methods, keeping it simple and focused.

Define Subpaths with Class Methods

To handle a path like /profile/settings/notifications, simply add a method to your class matching the subpath structure:

Route attributes as alternative

You can also use the #[Route] if you prefer a more declarative approach:

Each segment after the base path (/profile) maps to a method, with subpath segments replaced by underscores (_).

Dynamic Path Segments

You can define dynamic subpaths by adding parameters to your method:

Accessing /profile/edit/123 triggers the edit() method with the parameter $id = 123.

Wildcard parameters

Additionally, you can use wildcard parameters (*) to map subpaths to parameters. For example, handling /profile/123/edit can be done like this:

Wildcard parameters are mapped in order, alongside subpaths. For example, /profile/123/edit/notification results in parameters 123 and notification.

Parameter types

Enums

You can use both PHP backed enumerations and regular enums as route parameters because Rammewerk will convert them automatically based on the given path argument.

The router will automatically convert the parameter to the type specified in the method signature.

Parameter class dependencies

You can use classes as parameters, and the router will resolve them via the dependency handler set during initialization:

The order of class dependencies doesn’t matter, but parameters extracted from the path must be in the correct order.

Binding a Path to a Specific Method

You can bind a route to a specific class method in its class by defining the method in the route definition:

This ensures the edit() method of the ProfileRoute class is always called when /profile/settings is accessed.

Wrapping Up Class-Based Routing

Less configuration? Checked! 🎉 Class-based routing keeps things straightforward. Adding new routes is as easy as defining methods in your handler classes. With type safety, support for required and optional parameters, and the flexibility of wildcards, you can build routes that adapt to your needs without unnecessary complexity.


📦 Dependency Injection

To manage dependencies for class-based and closure-based routes, as well as middleware, the router requires a dependency resolver. You must set this up during initialization by passing a closure to the constructor. This closure receives a class name and returns an instance of that class.

For a simple and efficient solution, check out Rammewerk Container.

This approach keeps your routes clean and ensures seamless dependency handling.

🛡️ Middleware

Middleware adds functionality to your routes, like authentication, logging, or caching, without cluttering your route classes. It acts as a layer that processes requests before they reach your route handler or modifies responses afterward.

Here’s how to add middleware to a route:

Middleware runs in the order it’s defined. Each middleware must have a handle method that processes the request and calls the next closure to continue:

Note: Even though the request object is optional (object|null), your middleware must define it as the first parameter of the handle() method. The handle() method must always receive two arguments: the given request object (or null) and the next closure to call.

Rammewerk Router also supports PSR-15 MiddlewareInterface. See PSR-15 Support for more information.

Request Handling - Dispatching

The router passes a request object to each middleware and the route handler. The request type is flexible; you can pass any object during dispatch:

While optional, it’s good practice to type-hint the request in your handle method and ensure it matches the request class passed during dispatch.

Rammewerk Router also supports PSR-7 ServerRequestInterface. See PSR-7 Support for more

Group Middleware

Use the group() method to apply middleware to multiple routes at once. This keeps your code clean and avoids repetitive middleware declarations.

Here’s an example:

In this example, both /products and /users routes share the same middleware (AuthMiddleware and LoggerMiddleware), applied in the defined order.

If you define middleware on a route inside the group, it will run before the group’s middleware:

Here, AuthMiddleware runs first for /products, followed by LoggerMiddleware from the group. This lets you control the middleware order for each route.

Wrapping Up Middleware

Little configuration? Checked! 🎉 Middleware in the router is flexible and straightforward, letting you add layers to your routes without overcomplicating things. You’re free to implement middleware however you like — no restrictions on which request class to use or how to handle it.


🚀 Dispatching and Response

Dispatching routes is simple: just call the dispatch method on your router instance.

🚦 Method-Specific Request Handling

This router doesn’t predefine request types like GET or POST. It simply passes any request to the route. If you want to implement a get()/post()/delete() style structure, you can achieve it by adding a wrapper or using middleware to handle specific request methods. This gives you full flexibility to define request handling as you see fit.

🧩 Powerful Parameter Handling

This router shines with its robust and flexible parameter system:

This level of type safety, combined with flexible wildcards, is rare in other routers. It’s designed to make routing both powerful and effortless! 🚀

⚡ Performance and Speed

Rammewerk Router is designed to stay lean and move fast.

  1. It uses simple arrays to store routes and quickly narrows down matching paths by comparing only relevant segments.
  2. Regex patterns are sorted by length so more specific routes are tested first.
  3. Reflection is only performed once a route is confirmed, so there’s no overhead for routes that don’t match
  4. With minimal internal complexity, no bulky dependencies, and a single-file core, the router focuses on doing one job well without slowing you down in production.

Integrating Rammewerk Container can boost speed even more, thanks to its lazy-loading approach. It’s also one of the fastest DI containers out there, as shown in benchmarks.

🪶 Closure-Based Routes

While class-based routing is the core feature of Rammewerk Router, closure-based routes can be useful for simple, standalone handlers or quick prototypes.

These routes still benefit from the same powerful parameter handling as class-based routes, including dependency injection of classes and type-hinted subpath parameters. Middleware can also be applied seamlessly to closure-based routes, ensuring consistent behavior across your application.

Here’s an example:

Key Points:

Closure-based routes provide a lightweight yet flexible alternative when you don’t need a dedicated class handler.

🌐 PSR-7 & PSR-15 Support

The Rammewerk Router includes an extended class, PsrRouter, designed specifically for applications requiring PSR-7 (HTTP Message Interface) and PSR-15 (Middleware and Request Handlers) compliance. Use PsrRouter as a drop-in replacement for the default Router when working with PSR-compliant middleware and request handlers.

Highlights

Here's an example of PSR-7 & PSR-15 Usage:

The PsrRouter not only provides PSR-7 and PSR-15 support but also serves as an example of how to extend the Rammewerk Router to implement custom solutions tailored to specific application needs. This showcases the flexibility of the Rammewerk Router’s architecture, enabling developers to adapt it to various standards or unique requirements.

NOTE: If your project requires getAttribute() or similar functionality to handle parameters directly, the Rammewerk Router might not be the ideal solution for your needs. This router is designed for flexibility and handles parameters differently, with logic tailored to its specific architecture. If you’re looking for a router that supports named parameters or simpler routing logic, you may want to consider alternatives that are more closely aligned with your project’s requirements.

Here’s an updated section for your README documentation to reflect the usage and rules for Route attributes:

🛠 Route Attributes

The #[Route] attribute allows you to define routes directly on classes and methods for a clean and declarative approach to routing.

Class-Level Route Attribute:

Method-Level Route Attribute:

Why This Approach?

🏃 Benchmark

Rammewerk Router is designed for speed and minimal overhead, ensuring fast route resolution even in complex scenarios.

This benchmark test was conducted on PHP 8.4 CLI, calling a PHP-FPM server with opcache enabled via curl. Each router was warmed up before testing to ensure a fair comparison.

Benchmark Setup:

Rank Container Time (ms) Time (%) Peak Memory (MB) Peak Memory (%)
1 Rammewerk Router 79.959 100% 1.287 100%
2 FastRoute 175.513 220% 0.788 61%
3 PHRoute 192.192 240% 0.937 73%
4 Symfony Router 491.643 615% 0.817 64%

Key Takeaways:

More extensive benchmarks and detailed performance tests will be available in a dedicated GitHub repository soon. 🚀


All versions of router with dependencies

PHP Build Version
Package Version
Requires php Version >=8.4
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 rammewerk/router contains the following files

Loading the files please wait ....