practical capstone projects

Minimal Router

A router maps an HTTP method and path to application code. Add a small router to the catalog app so the product pages use one front controller instead of separate public PHP scripts.

Route Through One Entry Point

Configure the local server to send requests through public/index.php:

php -S 127.0.0.1:8000 -t public public/index.php

Inside the front controller, read the request method and URL path. Keep the supported surface explicit:

PHP example
<?php

$routes = [
    ['GET', '/products', [$productController, 'index']],
    ['GET', '/products/create', [$productController, 'create']],
    ['POST', '/products', [$productController, 'store']],
];

Match method and path deliberately. For /products/{id}, use a constrained numeric pattern, cast the captured value to an integer, and pass it to the handler. Never use URL text to choose a PHP filename for include.

Keep Failure Outcomes Distinct

Return 404 Not Found when no path matches. Return 405 Method Not Allowed when the path exists but the HTTP method is unsupported. That distinction helps clients and developers debug incorrect requests.

This router is for learning. Once routing, middleware, and error handling grow, use the router supplied by a maintained framework rather than expanding a home-grown framework.

Verify The Surface

Check product list, detail, create form, create POST, unknown path, unsupported method, and a non-numeric product ID.

Practice

Practice: Build A Tiny Product Router

Implement routing for product list, detail, create form, and create POST endpoints through public/index.php.

Requirements

  • Match method and path deliberately.
  • Extract route parameters without accepting arbitrary file paths or code names.
  • Return 404 and 405 outcomes separately.
  • Keep handlers separate from routing tables.
  • Do not build a production framework accidentally.
  • Avoid dynamic includes based on URL text.
  • Treat decoded parameters as untrusted input.

Verify 404, 405, and invalid-ID paths as well as normal routes.

Show solution

Use one front controller and a small explicit table. Normalize the URL path with parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH). Match static routes first, then constrained parameter routes such as #^/products/(\d+)$#.

When a path exists with a different method, return 405. When no route exists, return 404. Dispatch callable handlers directly; do not derive filenames or class names from request text.