### 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