### Start Built-in PHP Server
Source: https://github.com/auraphp/aura.router/blob/3.x/docs/getting-started.md
Run the built-in PHP development server to test the routing example. Ensure the web root is set to the current directory.
```bash
$ php -S localhost:8000 -t .
```
--------------------------------
### Aura.Router Basic Routing Example
Source: https://github.com/auraphp/aura.router/blob/3.x/docs/getting-started.md
This PHP script demonstrates setting up a router, defining a GET route for blog posts, matching a request, and dispatching a handler. It uses Laminas Diactoros for PSR-7 request and response objects.
```php
getMap();
// add a route to the map, and a handler for it
$map->get('blog.read', '/blog/{id}', function ($request) {
$id = (int) $request->getAttribute('id');
$response = new Laminas\Diactoros\Response();
$response->getBody()->write("You asked for blog entry {$id}.");
return $response;
});
// get the route matcher from the container ...
$matcher = $routerContainer->getMatcher();
// .. and try to match the request to a route.
$route = $matcher->match($request);
if (! $route) {
echo "No route found for the request.";
exit;
}
// add route attributes to the request
foreach ($route->attributes as $key => $val) {
$request = $request->withAttribute($key, $val);
}
// dispatch the request to the route handler.
// (consider using https://github.com/auraphp/Aura.Dispatcher
// in place of the one callable below.)
$callable = $route->handler;
$response = $callable($request);
// emit the response
foreach ($response->getHeaders() as $name => $values) {
foreach ($values as $value) {
header(sprintf('%s: %s', $name, $value), false);
}
}
http_response_code($response->getStatusCode());
echo $response->getBody();
```
--------------------------------
### JSON API Example
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Accepts.md
Sets up routes for a JSON API, ensuring all endpoints only accept 'application/json'. This example demonstrates configuring multiple routes for a consistent API format.
```php
getMap();
// All JSON API routes
$map->get('api.users', '/api/users', 'API\UsersController@list')
->accepts('application/json');
$map->get('api.user', '/api/users/{id}', 'API\UsersController@read')
->accepts('application/json')
->tokens(['id' => '\d+']);
$map->post('api.user.create', '/api/users', 'API\UsersController@create')
->accepts('application/json');
```
--------------------------------
### Complete Setup with Custom Rule Replacement
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/RuleIterator.md
Illustrates a complete setup where default rules are iterated, a specific rule (Special) is excluded, and a custom rule is added to the end before updating the iterator.
```php
getRuleIterator();
// Customize the rules
// Remove the default Special rule and replace with custom
$rules = [];
foreach ($iterator as $rule) {
if (!($rule instanceof Rule\Special)) {
$rules[] = $rule;
}
}
// Add custom rule at the end
$rules[] = new CustomRule();
// Update the iterator
$iterator->set($rules);
// Now when matching, the custom rule is used instead of Special
$matcher = $container->getMatcher();
$route = $matcher->match($request);
?>
```
--------------------------------
### JSON API Example
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Accepts.md
An example demonstrating how to configure multiple JSON-only routes using the `accepts()` method for a JSON API.
```APIDOC
## JSON API
```php
getMap();
// All JSON API routes
$map->get('api.users', '/api/users', 'API\UsersController@list')
->accepts('application/json');
$map->get('api.user', '/api/users/{id}', 'API\UsersController@read')
->accepts('application/json')
->tokens(['id' => '\d+']);
$map->post('api.user.create', '/api/users', 'API\UsersController@create')
->accepts('application/json');
```
```
--------------------------------
### RESTful API Routes Example
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Allows.md
Sets up common RESTful API routes for a 'posts' resource, including collection and individual resource routes with appropriate HTTP methods (GET, POST, PUT, PATCH, DELETE).
```php
getMap();
// Collection routes
$map->get('posts.list', '/posts', 'PostsController@list');
$map->post('posts.create', '/posts', 'PostsController@create');
// Resource routes
$map->get('posts.read', '/posts/{id}', 'PostsController@read')
->tokens(['id' => '\d+']);
$map->put('posts.update', '/posts/{id}', 'PostsController@update')
->tokens(['id' => '\d+']);
$map->patch('posts.patch', '/posts/{id}', 'PostsController@patch')
->tokens(['id' => '\d+']);
$map->delete('posts.delete', '/posts/{id}', 'PostsController@delete')
->tokens(['id' => '\d+']);
```
--------------------------------
### Complete Aura Router Matching Example
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Matcher.md
This comprehensive example demonstrates the full lifecycle of route matching in Aura Router. It covers setting up the router, defining various routes (GET, POST, with tokens and accepts conditions), creating a server request, attempting to match the request against the defined routes, and handling both successful matches and different types of routing failures (method not allowed, not found, content type not acceptable).
```php
getMap();
$matcher = $container->getMatcher();
// Define routes
$map->get('home', '/', 'HomeController@index');
$map->get('blog.read', '/blog/{id}', 'BlogController@read')
->tokens(['id' => '\d+']);
$map->post('blog.create', '/blog', 'BlogController@create');
$map->get('api.users', '/api/users', 'API\UsersController@list')
->accepts(['application/json']);
// Create a request
$request = ServerRequestFactory::fromGlobals(
$_SERVER,
$_GET,
$_POST,
$_COOKIE,
$_FILES
);
// Attempt to match
$route = $matcher->match($request);
if ($route) {
// Route matched
echo "Matched route: " . $route->name . "\n";
echo "Handler: " . $route->handler . "\n";
// Get path parameters
foreach ($route->attributes as $key => $value) {
echo "{$key} = {$value}\n";
}
// Dispatch the route
$handler = $route->handler;
// ... call the handler ...
} else {
// No match found
$failedRoute = $matcher->getFailedRoute();
if ($failedRoute) {
$failedRule = $failedRoute->failedRule;
if ($failedRule === 'Aura\Router\Rule\Allows') {
// Path matched but method not allowed
header('HTTP/1.1 405 Method Not Allowed');
echo "Method not allowed";
} else if ($failedRule === 'Aura\Router\Rule\Path') {
// No path matched
header('HTTP/1.1 404 Not Found');
echo "Not found";
} else if ($failedRule === 'Aura\Router\Rule\Accepts') {
// Content type not acceptable
header('HTTP/1.1 406 Not Acceptable');
echo "Content type not acceptable";
}
} else {
// No routes defined at all
header('HTTP/1.1 404 Not Found');
echo "Not found";
}
}
?>
```
--------------------------------
### Basic Path Matching Examples
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Path.md
Define routes with static path segments for exact matching.
```php
$map->get('home', '/');
$map->get('about', '/about');
$map->post('contact', '/contact/submit');
```
--------------------------------
### Complete Aura Router Generator Example
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Generator.md
A comprehensive example demonstrating route definition and path generation with various features including parameters, defaults, wildcards, and basepaths.
```php
getMap();
$generator = $container->getGenerator();
// Define routes with various features
$map->get('home', '/', 'HomeController@index');
$map->get('blog.read', '/blog/{id}', 'BlogController@read')
->tokens(['id' => '\d+']);
$map->post('blog.create', '/blog', 'BlogController@create');
$map->get('user.profile', '/users/{username}', 'UserController@profile')
->tokens(['username' => '[a-z0-9]+']);
$map->get('search', '/search{/query,page,limit}', 'SearchController@search')
->defaults(['query' => '', 'page' => 1, 'limit' => 10]);
$map->get('files', '/files/*', 'FilesController@read')
->wildcard('segments');
// Generate paths
echo $generator->generate('home');
// Output: "/"
echo $generator->generate('blog.read', ['id' => 42]);
// Output: "/blog/42"
echo $generator->generate('user.profile', ['username' => 'john']);
// Output: "/users/john"
echo $generator->generate('search', ['query' => 'hello world']);
// Output: "/search/hello%20world"
echo $generator->generate('search', ['query' => 'php', 'page' => 2, 'limit' => 20]);
// Output: "/search/php/2/20"
echo $generator->generate('files', ['segments' => ['docs', 'readme.md']]);
// Output: "/files/docs/readme.md"
// Using raw generation (no encoding)
echo $generator->generateRaw('search', ['query' => 'hello world']);
// Output: "/search/hello world"
// Using with basepath
$container2 = new RouterContainer('/myapp/v2');
$generator2 = $container2->getGenerator();
echo $generator2->generate('home');
// Output: "/myapp/v2/"
?>
```
--------------------------------
### Example: Public Routes (Any Protocol)
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Secure.md
Configure public-facing routes that can be accessed via either HTTP or HTTPS.
```php
get('home', '/', 'homecontroller@index');
// secure(null) - default, accepts both HTTP and HTTPS
$map->get('about', '/about', 'pagecontroller@about');
// secure(null) - default
$map->get('blog', '/blog', 'blogcontroller@index');
// secure(null) - default
```
--------------------------------
### Install Aura.Router and Zend-Diactoros
Source: https://github.com/auraphp/aura.router/blob/3.x/docs/getting-started.md
Use Composer to install the necessary libraries for Aura.Router and request/response handling.
```bash
$ composer require aura/router zendframework/zend-diactoros
```
--------------------------------
### Complete Example: Defining and Generating Routes
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Route-Helper.md
Demonstrates defining multiple routes and then using the Route helper to generate their corresponding URL paths in PHP code.
```php
getMap();
$helper = $container->newRouteHelper();
// Define routes
$map->get('home', '/', 'HomeController@index');
$map->get('blog.list', '/blog', 'BlogController@list');
$map->get('blog.read', '/blog/{id}', 'BlogController@read')
->tokens(['id' => '\d+']);
$map->get('user.profile', '/users/{username}', 'UserController@profile');
// Generate paths
$home = $helper('home');
// "/"
$blog = $helper('blog.list');
// "/blog"
$post = $helper('blog.read', ['id' => 42]);
// "/blog/42"
$profile = $helper('user.profile', ['username' => 'john']);
// "/users/john"
// Multiple parameters
$post = $helper('blog.read', ['id' => 123]);
// "/blog/123"
// With URL encoding (spaces become %20)
$search = $helper('search', ['query' => 'hello world']);
// "/search/hello%20world"
```
--------------------------------
### Complete Route Configuration Example
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Route.md
Demonstrates a comprehensive configuration of a Route object, setting its name, path, allowed methods, handler, tokens, defaults, security, and attributes.
```php
name('blog.read')
->path('/blog/{id}')
->allows(['GET', 'HEAD'])
->handler('BlogController@read')
->tokens(['id' => '\d+'])
->defaults(['id' => null])
->secure(true)
->attributes(['id' => null]);
// Now you can read properties
echo $route->name; // 'blog.read'
echo $route->path; // '/blog/{id}'
```
--------------------------------
### Subdomain-Based Routing Example
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Host.md
Configures routes for a main site, an API subdomain, and tenant-specific subdomains, demonstrating host-based routing.
```php
getMap();
// Main site
$map->get('home', '/', 'HomeController@index')
->host('example.com');
$map->get('blog', '/blog', 'BlogController@index')
->host('example.com');
// API subdomain
$map->get('api.users', '/users', 'API\UsersController@list')
->host('api.example.com');
// Tenant subdomains
$map->get('tenant.home', '/', 'TenantController@home')
->host('{tenant}.example.com');
$map->get('tenant.dashboard', '/dashboard', 'TenantController@dashboard')
->host('{tenant}.example.com');
```
--------------------------------
### get()
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Map.md
Adds a GET route.
```APIDOC
## get()
### Description
Adds a GET route.
### Method
`get($name, $path, $handler = null) : Route`
### Parameters
#### Path Parameters
* None
#### Query Parameters
* None
#### Request Body
* None
### Request Example
```php
get('home', '/', 'HomeController@index');
$map->get('blog.read', '/blog/{id}', 'BlogController@read');
```
### Response
#### Success Response
* Returns `Route` — The newly-added route object
#### Response Example
* None
### Throws
* `Exception\ImmutableProperty`
* `Exception\RouteAlreadyExists`
```
--------------------------------
### Basic Router Setup and Matching
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/README.md
Initializes the RouterContainer, adds routes to the map, and matches an incoming server request. Requires Laminas Diactoros for PSR-7 request creation.
```php
getMap();
$map->get('home', '/', 'HomeController@index');
$map->get('blog.read', '/blog/{id}', 'BlogController@read');
// Match a request
$request = ServerRequestFactory::fromGlobals();
$matcher = $container->getMatcher();
$route = $matcher->match($request);
if ($route) {
// Route matched
echo "Handler: " . $route->handler;
} else {
echo "No route matched";
}
```
--------------------------------
### Complete Aura Router Example
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/RouterContainer.md
Demonstrates the full lifecycle of Aura Router: container creation, route definition, request matching, and path generation.
```php
getMap();
$map->get('home', '/', function($request, $response) {
$response->getBody()->write('Home page');
return $response;
});
$map->get('blog.read', '/blog/{id}', function($request, $response) {
$id = $request->getAttribute('id');
$response->getBody()->write("Blog post: {$id}");
return $response;
});
// Get the matcher and match a request
$matcher = $container->getMatcher();
$route = $matcher->match($request);
if ($route) {
// Route matched, can access matched route attributes
$id = $request->getAttribute('id');
} else {
// No route matched
$failedRoute = $matcher->getFailedRoute();
}
// Generate paths using the generator
$generator = $container->getGenerator();
$path = $generator->generate('blog.read', ['id' => 42]);
// Result: "/myapp/blog/42"
?>
```
--------------------------------
### Matcher Constructor Example
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Matcher.md
Instantiate a new Matcher object using the RouterContainer. This sets up the necessary components for route matching.
```php
getMatcher();
```
--------------------------------
### Example: Mixed Security Configuration
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Secure.md
Set up a router with a mix of public, private (HTTPS-only), and API routes, demonstrating varied security requirements.
```php
getmap();
// Public routes - any protocol
$map->get('home', '/', 'homecontroller@index');
$map->get('about', '/about', 'pagecontroller@about');
// Private routes - HTTPS only
$map->get('dashboard', '/dashboard', 'dashboardcontroller@index')
->secure(true);
$map->post('user.update', '/user', 'usercontroller@update')
->secure(true);
$map->get('settings', '/settings', 'settingscontroller@index')
->secure(true);
// API routes - usually HTTPS only
$map->attach('api', '/api', function($map) {
$map->get('users', '/users', 'api\userscontroller@list')
->secure(true);
$map->post('users', '/users', 'api\userscontroller@create')
->secure(true);
});
```
--------------------------------
### Wildcard Token Usage Example
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Path.md
Demonstrates how wildcard tokens capture multiple path segments into an array attribute.
```php
get('file.serve', '/files/*')
->wildcard('filepath');
// Request: /files/docs/readme.md
// Extracted: $route->attributes['filepath'] = ['docs', 'readme.md']
// Request: /files/a/b/c/d/e/file.tar.gz
// Extracted: $route->attributes['filepath'] = ['a', 'b', 'c', 'd', 'e', 'file.tar.gz']
```
--------------------------------
### Add a GET Route with a Handler
Source: https://github.com/auraphp/aura.router/blob/3.x/docs/getting-started.md
Add a GET route named 'blog.read' to the map. This route matches '/blog/{id}' and executes a closure to handle the request, writing to the response body.
```php
getMap();
$map->get('blog.read', '/blog/{id}', function ($request, $response) {
$id = (int) $request->getAttribute('id');
$response->getBody()->write("You asked for blog entry {$id}.");
return $response;
});
?>
```
--------------------------------
### Instantiate Allows Rule
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Allows.md
Creates a new instance of the Allows rule. This is the basic setup for using the rule.
```php
get('api.data', '/api/data', 'DataController@fetch')
->accepts(['application/json', 'application/xml']);
// Serves JSON, XML, or CSV
$map->get('api.export', '/api/export', 'DataController@export')
->accepts(['application/json', 'application/xml', 'text/csv']);
```
```
--------------------------------
### Basic Path Matching
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Path.md
Define and match simple GET routes for home, about, and a blog post with an ID. Requires Aura\Router\RouterContainer and Laminas\Diactoros\ServerRequestFactory.
```php
getMap();
// Define routes
$map->get('home', '/');
$map->get('about', '/about');
$map->get('blog.read', '/blog/{id}');
// Create a request
$factory = ServerRequestFactory::class;
$request = $factory::fromGlobals();
// Match
$matcher = $container->getMatcher();
$route = $matcher->match($request);
if ($route && $route->name === 'blog.read') {
$id = $request->getAttribute('id');
echo "Blog post {$id}";
}
```
--------------------------------
### Instantiate Accepts Rule
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Accepts.md
Creates a new instance of the Accepts rule. This is the basic setup before configuring accepted content types.
```php
getMap();
$matcher = $container->getMatcher();
$generator = $container->getGenerator();
// Define routes
try {
$map->get('home', '/', 'HomeController@index');
$map->get('blog.read', '/blog/{id}', 'BlogController@read')
->tokens(['id' => '\d+']);
} catch (Exception\RouteAlreadyExists $e) {
die("Duplicate route name: " . $e->getMessage());
} catch (Exception\ImmutableProperty $e) {
die("Cannot modify immutable property: " . $e->getMessage());
}
// Match request
try {
$route = $matcher->match($request);
} catch (Exception $e) {
die("Error during matching: " . $e->getMessage());
}
// Generate path
try {
$path = $generator->generate('blog.read', ['id' => 42]);
} catch (Exception\RouteNotFound $e) {
die("Route for path generation not found");
} catch (RuntimeException $e) {
die("Invalid parameter for route: " . $e->getMessage());
}
// Use helper
try {
$url = $routeHelper('blog.read', ['id' => '123']);
} catch (Exception\RouteNotFound $e) {
echo "Cannot generate URL: route not found";
}
```
--------------------------------
### Authentication Check Example
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Special.md
Demonstrates using the special rule to check if a user is authenticated and has administrative privileges before matching a route.
```php
getMap();
$map->get('admin', '/admin', 'AdminController@dashboard')
->special(function($request, $route) {
// Check if user is authenticated and is admin
$user = $request->getAttribute('user');
return $user && $user->isAdmin();
});
```
--------------------------------
### Different Routes for Different Formats Example
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Accepts.md
Shows how to define separate routes for different content types (HTML, JSON, XML) for the same resource, allowing for distinct handling of each format.
```APIDOC
## Different Routes for Different Formats
```php
get('blog.read.html', '/blog/{id}', 'BlogController@readHtml')
->accepts('text/html');
// JSON API endpoint
$map->get('blog.read.json', '/blog/{id}', 'BlogController@readJson')
->accepts('application/json')
->tokens(['id' => '\d+']);
// XML endpoint
$map->get('blog.read.xml', '/blog/{id}', 'BlogController@readXml')
->accepts('application/xml')
->tokens(['id' => '\d+']);
```
```
--------------------------------
### Accepts Rule with Multiple Content Types and Q-Values
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Accepts.md
This example shows how to define a route that accepts multiple content types using the `accepts()` method. The router automatically handles quality factors (q-values) specified in the client's Accept header.
```php
get('data', '/data', 'DataController@get')
->accepts(['application/json', 'application/xml']);
// For the above Accept header:
// - Client accepts JSON with q=1.0
// - Client accepts XML with q=0.8
// - Route accepts both
// - Rule passes because there's a match at any quality > 0
```
--------------------------------
### Example: HTTP-Only Routes
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Secure.md
Define routes that are specifically intended for HTTP connections only, which is an uncommon but possible configuration.
```php
get('status', '/status', 'statuscontroller@check')
->secure(false);
```
--------------------------------
### Database Validation Example
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Special.md
Shows how to use the special rule to validate if a requested resource, identified by an ID, exists in the database before matching the route.
```php
get('post', '/blog/{id}', 'BlogController@read')
->tokens(['id' => '\d+'])
->special(function($request, $route) use ($db) {
// Validate that the post exists
$id = $request->getAttribute('id');
return $db->postExists($id);
});
```
--------------------------------
### Route Name Immutability Example
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/errors.md
Illustrates attempting to set a route's name twice, which triggers an ImmutableProperty exception.
```php
name('first');
$route->name('second');
// Exception\ImmutableProperty: Route::$name is immutable once set
```
--------------------------------
### Host Matching with Placeholder Tokens
Source: https://github.com/auraphp/aura.router/blob/3.x/docs/defining-routes.md
Define host matching with placeholder tokens to capture parts of the domain, such as subdomains, as route attributes. The example captures the subdomain from '*.example.com'.
```php
get('blog.browse', '/blog')
->host('{subdomain}.?example.com');
?>
```
--------------------------------
### Environment-Based Router Configuration
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/configuration.md
Configure Aura Router based on environment variables. This example enables logging only in non-production environments.
```php
setLoggerFactory(function() {
$logger = new Logger('router');
$logger->pushHandler(new StreamHandler('php://stderr', Logger::DEBUG));
return $logger;
});
}
// Define routes
$container->setMapBuilder(function($map) {
$map->get('home', '/', 'HomeController@index');
// ... more routes
});
```
--------------------------------
### Set All Matching Rules Including Custom
Source: https://github.com/auraphp/aura.router/blob/3.x/docs/custom-matching.md
This example illustrates how to replace the entire set of matching rules in the RouterContainer with a custom list. It's important to include both default and custom rules when using this method.
```php
use Aura\Router\Rule;
$routerContainer->getRuleIterator()->set([
// default rules
new Rule\Secure(),
new Rule\Host(),
new Rule\Path(),
new Rule\Allows(),
new Rule\Accepts(),
new Rule\Special(),
// custom rule
new ApiVersionRule()
]);
```
--------------------------------
### Query Parameter Validation Example
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Special.md
Demonstrates using the special rule to enforce that a search route requires at least one query parameter ('q' or 'category') to be present.
```php
$map->get('search', '/search', 'SearchController@search')
->special(function($request, $route) {
// Require at least one search parameter
$params = $request->getQueryParams();
return !empty($params['q']) ||
!empty($params['category']);
});
```
--------------------------------
### Defining Simple Routes
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/README.md
Defines routes with different HTTP methods (GET, POST, PUT, DELETE) and their corresponding paths and handlers.
```php
$map->get('home', '/', 'HomeController@index');
$map->post('contact.submit', '/contact', 'ContactController@submit');
$map->put('user.update', '/users/{id}', 'UserController@update');
$map->delete('user.delete', '/users/{id}', 'UserController@delete');
```
--------------------------------
### Define Route with Dynamic Subdomain Extraction
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Host.md
This example illustrates how to define a route that matches a dynamic subdomain structure. It uses the `host()` method with multiple placeholders and `tokens()` to define patterns for each subdomain, allowing for flexible matching of various subdomains.
```php
get('dynamic', '/')
->host('{subdomain1}.{subdomain2}.example.com')
->tokens([
'subdomain1' => '[a-z]+',
'subdomain2' => '[a-z]+'
]);
// Request to: blog.api.example.com
// Extracts: subdomain1 = 'blog', subdomain2 = 'api'
```
--------------------------------
### Complete Router Configuration Example
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/configuration.md
This snippet shows a comprehensive configuration of Aura Router, including setting a basepath, custom logger, custom route factory, defining routes via a map builder, and adding custom rules.
```php
setLoggerFactory(function() {
$logger = new Logger('router');
$logger->pushHandler(new StreamHandler('php://stderr'));
return $logger;
});
// Configure custom route class
$container->setRouteFactory(function() {
return new MyCustomRoute();
});
// Configure map builder
$container->setMapBuilder(function($map) {
// Public routes
$map->get('home', '/', 'HomeController@index');
$map->get('about', '/about', 'PageController@about');
// API routes
$map->attach('api', '/api', function($map) {
$map->get('users', '/users', 'API\UsersController@list');
$map->get('user', '/users/{id}', 'API\UsersController@read')
->tokens(['id' => '\d+']);
});
// Admin routes
$map->attach('admin', '/admin', function($map) {
$map->get('dashboard', '', 'AdminController@dashboard');
$map->get('users', '/users', 'AdminController@users');
})
->secure(true); // All admin routes require HTTPS
});
// Customize rules
$iterator = $container->getRuleIterator();
// Add authentication rule
$iterator->append(new class implements RuleInterface {
public function __invoke(ServerRequestInterface $request, Route $route) {
// Custom logic
return true;
}
});
// Use the container
$map = $container->getMap();
$matcher = $container->getMatcher();
$generator = $container->getGenerator();
```
--------------------------------
### Building HTML Links for Dynamic Content
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Route-Helper.md
Example of generating HTML links for a list of items (e.g., blog posts) where each link's URL is created using the Route helper with item-specific parameters.
```php
newRouteHelper();
// Dynamically generate links
$posts = [
['id' => 1, 'title' => 'First Post'],
['id' => 2, 'title' => 'Second Post'],
];
foreach ($posts as $post) {
$url = $helper('blog.read', ['id' => $post['id']]);
echo "{$post['title']}
";
}
```
--------------------------------
### User-Specific Routes Example
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Special.md
Illustrates using the special rule to restrict access to a route, ensuring only the logged-in user can view their own profile based on a username attribute.
```php
$map->get('user.profile', '/users/{username}', 'UserController@profile')
->special(function($request, $route) {
// Only the user themselves can view their profile
$username = $request->getAttribute('username');
$currentUser = $request->getAttribute('user');
return $currentUser &&
$currentUser->getUsername() === $username;
});
```
--------------------------------
### Configure Custom Map Factory
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/configuration.md
Configure how the route map is created. The default creates new Map() instances with the proto-route. This example shows creating a map with caching support.
```php
setmapfactory(function() {
return new cachedmap($container->getroute());
});
```
--------------------------------
### Port-Based Routing Example
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Host.md
Defines routes that are matched based on both the host and the specific port number. This is useful for running different applications or services on the same host but different ports.
```php
get('admin', '/', 'AdminController@index')
->host('example.com:8080');
$map->get('app', '/', 'AppController@index')
->host('example.com:8000');
```
--------------------------------
### Get the Path Generator
Source: https://github.com/auraphp/aura.router/blob/3.x/docs/generating-paths.md
Retrieve the Generator instance from the RouterContainer to start creating paths.
```php
getGenerator();
?>
```
--------------------------------
### Rate Limiting Example
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Special.md
Implements a rate limiting mechanism using the special rule to control the number of requests from a specific IP address within a time window.
```php
limits[$key])) {
$this->limits[$key] = ['count' => 0, 'window' => $now];
}
if ($now - $this->limits[$key]['window'] > 60) {
// Reset window
$this->limits[$key] = ['count' => 1, 'window' => $now];
return true;
}
$this->limits[$key]['count']++;
return $this->limits[$key]['count'] <= 100; // 100 req/min
}
}
$limiter = new RateLimiter();
$map->get('api.data', '/api/data', 'API\DataController@fetch')
->special(function($request, $route) use ($limiter) {
$ip = $request->getServerParams()['REMOTE_ADDR'];
return $limiter->isAllowed($ip);
});
```
--------------------------------
### Implement a Custom API Version Rule
Source: https://github.com/auraphp/aura.router/blob/3.x/docs/custom-matching.md
This example shows how to create a custom rule that checks for a specific 'X-Api-Version' header. The rule passes if the header is present and unique, capturing its value into route attributes.
```php
getHeader('X-Api-Version');
if (count($versions) !== 1) {
return false;
}
$route->attributes(['apiVersion' => $versions[0]]);
return true;
}
}
?>
```
--------------------------------
### Instantiate RouterContainer with Base Path
Source: https://github.com/auraphp/aura.router/blob/3.x/docs/other-topics.md
Create a RouterContainer with an explicit base path to handle URLs that start in a subdirectory. This base path is used for both route matching and path generation.
```php
getMap();
$map->get('blog.read', '/blog/{id}', ...);
// if the incoming request is for "/path/to/subdir/blog/{id}"
// then the route will match.
$matcher = $routerContainer->getMatcher();
$route = $matcher->match($request);
// generating a path from the route will add the base path automatically
$generator = $routerContainer->getGenerator();
$path = $generator->generate('blog.read', ['id' => 88]);
echo $path; // "/path/to/subdir/blog/88"
?>
```
--------------------------------
### Define Routes with HTTP Method Shortcuts
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Allows.md
Uses convenient methods on the Map class to define routes for specific HTTP methods like GET, POST, PUT, DELETE, etc. These shortcuts automatically configure the route's allowed methods.
```php
$map->get('home', '/', 'HomeController@index');
$map->post('contact', '/contact', 'ContactController@submit');
$map->put('user', '/users/{id}', 'UserController@update');
$map->patch('user', '/users/{id}', 'UserController@patch');
$map->delete('user', '/users/{id}', 'UserController@delete');
$map->head('user', '/users/{id}', 'UserController@head');
$map->options('user', '/users/{id}', 'UserController@options');
```
--------------------------------
### Implement Automated Route Map Building with Caching
Source: https://github.com/auraphp/aura.router/blob/3.x/docs/custom-maps.md
Set a map builder callable on the RouterContainer to automate route map construction, including caching. This example shows a naive file-based cache mechanism using `Map::setRoutes()` and `Map::getRoutes()`.
```php
setMapBuilder(function ($map) {
// the cache file location
$cache = '/path/to/routes.cache';
// does the cache exist?
if (file_exists($cache)) {
// restore from the cache
$routes = unserialize(file_get_contents($cache));
$map->setRoutes($routes);
} else {
// build the routes on the map ...
$map->get(...);
$map->post(...);
// ... then save them to the cache for the next page load
$routes = $map->getRoutes();
file_put_contents($cache, serialize($routes));
}
});
?>
```
--------------------------------
### Defining and Retrieving Routes with Aura Router
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Map.md
This snippet demonstrates how to instantiate the RouterContainer, get the map, define simple routes, routes with path parameters, optional segments, and grouped API routes. It also shows how to retrieve a specific route by name and iterate over all defined routes.
```php
getMap();
// Simple routes
$map->get('home', '/', 'HomeController@index');
$map->get('about', '/about', 'PageController@about');
// Routes with path parameters
$map->get('blog.read', '/blog/{id}', 'BlogController@read')
->tokens(['id' => '\d+']);
$map->post('blog.create', '/blog', 'BlogController@create');
// Routes with optional segments
$map->get('search', '/search{/query,page,limit}', 'SearchController@search')
->defaults(['query' => '', 'page' => 1, 'limit' => 10]);
// Grouped API routes with prefix
$map->attach('api.v1', '/api/v1', function($map) {
$map->get('users.list', '/users', 'API\UsersController@list');
$map->get('users.read', '/users/{id}', 'API\UsersController@read')
->tokens(['id' => '\d+']);
$map->post('users.create', '/users', 'API\UsersController@create');
$map->put('users.update', '/users/{id}', 'API\UsersController@update');
$map->delete('users.delete', '/users/{id}', 'API\UsersController@delete');
// Nested grouping
$map->attach('posts', '/posts', function($map) {
$map->get('list', '', 'API\PostsController@list');
$map->get('read', '/{id}', 'API\PostsController@read');
});
});
// Retrieve and verify routes
$blogRoute = $map->getRoute('blog.read');
echo $blogRoute->path; // '/blog/{id}'
echo $blogRoute->handler; // 'BlogController@read'
// Iterate over all routes
foreach ($map as $name => $route) {
echo "Route: {$name} -> {$route->path}";
}
?>
```
--------------------------------
### Add a GET Route
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Map.md
Adds a route specifically for handling GET requests. This is useful for retrieving resources.
```php
get('home', '/', 'HomeController@index');
$map->get('blog.read', '/blog/{id}', 'BlogController@read');
```
--------------------------------
### Example Rule: Method Allowance Check
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/RuleInterface.md
An example implementation of the __invoke method to check if the request's HTTP method is allowed by the route's configuration. It returns true if no method restriction is set or if the request method is in the allowed list.
```php
public function __invoke(ServerRequestInterface $request, Route $route)
{
// Example: Check if request method is allowed
if (!$route->allows) {
return true; // No restriction
}
$method = $request->getMethod() ?: 'GET';
return in_array($method, $route->allows);
}
```
--------------------------------
### Example: HTTPS-Only Routes
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Secure.md
Define sensitive routes that strictly require an HTTPS connection for security.
```php
getmap();
// Sensitive routes require HTTPS
$map->get('login', '/login', 'authcontroller@loginform')
->secure(true);
$map->post('login.submit', '/login', 'authcontroller@login')
->secure(true);
$map->get('admin', '/admin', 'admincontroller@dashboard')
->secure(true);
$map->get('account.settings', '/account/settings', 'accountcontroller@settings')
->secure(true);
```
--------------------------------
### Add a HEAD Route
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Map.md
Adds a route for handling HEAD requests, which are similar to GET but only retrieve headers.
```php
head('blog.head', '/blog/{id}', 'BlogController@head');
```
--------------------------------
### Get Generator Instance
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/RouterContainer.md
Access the shared Generator instance to create URLs from route names and parameters.
```php
getGenerator();
$path = $generator->generate('blog.read', ['id' => 42]);
```
--------------------------------
### Get Matcher Instance
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/RouterContainer.md
Obtain the shared Matcher instance for matching incoming requests against defined routes.
```php
getMatcher();
$route = $matcher->match($request);
if ($route) {
// Route matched
}
```
--------------------------------
### Building Navigation Menus with Route Helper
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Route-Helper.md
Demonstrates constructing a navigation array where URLs are generated dynamically using the Route helper.
```php
newRouteHelper();
$navigation = [
'Home' => $helper('home'),
'Blog' => $helper('blog.list'),
'About' => $helper('about'),
'Contact' => $helper('contact'),
];
foreach ($navigation as $label => $url) {
echo "{$label}";
}
```
--------------------------------
### Get Logger Instance
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/RouterContainer.md
Retrieve the shared logger instance, which defaults to a NullLogger. This is used for debugging route matching.
```php
getLogger();
// Logger records debug messages during route matching
```
--------------------------------
### Define Route with Host and Path Tokens
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Host.md
This snippet shows how to define a route that matches a specific host pattern with a dynamic tenant and a path pattern with a dynamic resource ID. It demonstrates the use of the `host()` and `tokens()` methods to extract parameters from both the host and the path.
```php
get('tenant.resource', '/resources/{id}')
->host('{tenant}.example.com')
->tokens([
'tenant' => '[a-z0-9\-]+',
'id' => '\d+'
]);
// Request to: acme.example.com/resources/42
// Extracts:
// - tenant = 'acme'
// - id = '42'
```
--------------------------------
### Get Map Instance
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/RouterContainer.md
Retrieve the shared Map instance to define and add routes. The map is built on first access.
```php
getMap();
$map->get('home', '/', function ($request, $response) {
return $response;
});
```
--------------------------------
### Create Host Rule Instance
Source: https://github.com/auraphp/aura.router/blob/3.x/_autodocs/api-reference/Host.md
Instantiates a new Host rule object. This is the initial step before applying host matching to routes.
```php