Skip to content

Quick start guide

Greg Bowler edited this page Apr 14, 2026 · 1 revision

In this guide we will install phpgt/routing, build a router class, pass in a PSR-7 request, and inspect the resulting assemblies.

Note

When building WebEngine applications, much of this setup is already done for us. WebEngine creates the request, configures the routing layer, and uses the path-matching tools in this repository as part of its request lifecycle. This guide is still useful because it shows the moving parts in isolation.

1. Install the package

composer require phpgt/routing

To follow the examples on this page as written, we also need a PSR-7 request implementation. The PHP.GT HTTP package fits naturally here:

composer require phpgt/http

2. Create a router class

The router extends GT\Routing\BaseRouter and uses attributes to mark routable methods.

use GT\Routing\BaseRouter;
use GT\Routing\Method\Get;
use GT\Routing\Method\Post;

class AppRouter extends BaseRouter {
	#[Get(path: "/")]
	public function home():void {
		$this->addToViewAssembly("page/index.html");
	}

	#[Post(path: "/contact", accept: "text/html")]
	public function submitContactForm():void {
		$this->addToLogicAssembly("page/contact.php");
		$this->addToViewAssembly("page/contact.html");
	}
}

At this point we have defined what should happen when the request is for /, and what should happen when it is a POST request to /contact.

3. Create a request

This library expects a PSR-7 request. Here we will use GT\Http\Request and GT\Http\Uri.

use GT\Http\Request;
use GT\Http\Uri;

$request = new Request("GET", new Uri("/"));

4. Route the request

Now we can instantiate the router and ask it to match the request:

$router = new AppRouter();
$router->route($request);

If a callback matches, it will be invoked and the assemblies will be filled.

5. Read the assemblies

The router has separate assemblies for logic and view paths, which are iterable containers of one type of file - for instance, the view assembly can contain all the HTML files that build up the current page view, and the logic assemble can contain all PHP files that need executing in order to produce the page logic:

foreach($router->getViewAssembly() as $path) {
	echo "View: $path", PHP_EOL;
}

foreach($router->getLogicAssembly() as $path) {
	echo "Logic: $path", PHP_EOL;
}

For the GET / request above, the output would include:

View: page/index.html

6. Add content negotiation

If we want more than one representation of the same URI, we can add accept values:

use GT\Routing\Method\Any;

class AppRouter extends BaseRouter {
	#[Any(path: "/report", accept: "text/html")]
	public function htmlReport():void {
		$this->addToViewAssembly("page/report.html");
	}

	#[Any(path: "/report", accept: "application/json")]
	public function jsonReport():void {
		$this->addToLogicAssembly("api/report.php");
	}
}

The router will compare those values against the request's Accept header and choose the best match.

7. Move on to file-based routing

The callback example above is enough to show the core routing flow, but the library also includes the path-matching tools used by WebEngine:

  • PathMatcher
  • BasicFileMatch
  • MagicFileMatch
  • DynamicPath
  • LogicStreamWrapper

Those tools are covered in the rest of the guide, starting with understanding routing and then path matching.


Next, continue with understanding routing for the wider picture of how callback matching and assemblies fit together.

Clone this wiki locally