PHP Classes

File: docs/routing/examples/Router_PatternMatching_README.md

Recommend this page to a friend!
  Packages of Adrian M   upMVC   docs/routing/examples/Router_PatternMatching_README.md   Download  
File: docs/routing/examples/Router_PatternMatching_README.md
Role: Documentation
Content type: text/markdown
Description: Documentation
Class: upMVC
Pure PHP web development without other frameworks
Author: By
Last change: up
Date: 2 months ago
Size: 4,185 bytes
 

Contents

Class file image Download

Router with Pattern Matching Support

This is a production-ready Router implementation that supports pattern matching with wildcards (*) and named parameters ({id}).

Features

  • ? Exact route matching (backward compatible)
  • ? Wildcard patterns: `/users/*/edit`
  • ? Named parameters: `/users/{id}/edit`
  • ? Complex patterns: `/books/{author}/{year}/{isbn}`
  • ? Parameters automatically added to `$_GET`
  • ? Middleware support (unchanged)

Installation

Replace src/Etc/Router.php with this file (v2.0 layout):

# Backup original
Copy-Item src/Etc/Router.php src/Etc/Router_BACKUP.php

# Install pattern matching router
Copy-Item docs/routing/examples/Router_PatternMatching.php src/Etc/Router.php -Force

Usage Examples

Basic Named Parameter

// In routes/Routes.php
$router->addRoute('/users/{id}', UserController::class, 'display');

// Matches: /users/123
// Result: $_GET['id'] = '123'

Multiple Parameters

$router->addRoute('/blog/{author}/{year}/{slug}', BlogController::class, 'display');

// Matches: /blog/john/2025/my-first-post
// Result:
//   $_GET['author'] = 'john'
//   $_GET['year'] = '2025'
//   $_GET['slug'] = 'my-first-post'

Wildcard Pattern

$router->addRoute('/admin/users/*/edit', AdminController::class, 'display');

// Matches: /admin/users/123/edit
// Note: Wildcard value is not captured (use {id} instead)

Controller Implementation

class UserController
{
    public function display()
    {
        // Parameter from pattern is in $_GET
        $userId = isset($_GET['id']) ? (int)$_GET['id'] : null;
        
        if (!$userId) {
            http_response_code(400);
            echo "Invalid user ID";
            return;
        }
        
        // Validate ID exists in database
        $user = $this->model->getUserById($userId);
        if (!$user) {
            http_response_code(404);
            echo "User not found";
            return;
        }
        
        // Display user
        $this->view->render(['user' => $user]);
    }
}

Pattern Conversion Reference

| Pattern | Regex | Matches | Parameters | |---------|-------|---------|------------| | /users/{id} | /^\/users\/(?P<id>[^\/]+)$/ | /users/123 | $_GET['id'] = '123' | | /users/* | /^\/users\/([^\/]+)$/ | /users/123 | None captured | | /blog/{category}/{slug} | /^\/blog\/(?P<category>[^\/]+)\/(?P<slug>[^\/]+)$/ | /blog/tech/hello-world | $_GET['category'] = 'tech'<br>$_GET['slug'] = 'hello-world' |

Important Notes

Security Considerations

Pattern matching allows any value to match the pattern. You must validate in your controller:

// ? BAD - No validation
$userId = $_GET['id'];
$user = $this->model->getUserById($userId); // SQL injection risk!

// ? GOOD - Validate and sanitize
$userId = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ($userId <= 0) {
    http_response_code(400);
    return;
}
$user = $this->model->getUserById($userId);
if (!$user) {
    http_response_code(404);
    return;
}

Route Priority

Routes are checked in this order: 1. Exact match - /users/123 matches route /users/123 2. Pattern match - /users/123 matches pattern /users/{id} 3. 404 - No match found

To avoid conflicts, define specific routes before patterns:

// Specific routes first
$router->addRoute('/users/add', UserController::class, 'add');
$router->addRoute('/users/list', UserController::class, 'list');

// Pattern routes last
$router->addRoute('/users/{id}', UserController::class, 'display');

Performance

Pattern matching uses regex, which is very fast: - Exact match: ~0.1ms - Pattern match: ~0.5ms

Even with 100 routes, total routing time is < 1ms.

Rollback

If you need to go back to the original Router:

Copy-Item etc/Router_BACKUP.php etc/Router.php -Force

See Also