Example project
The repository includes a project under example/project/simple-site/ that shows how the pieces fit together.
It is not a full framework. Its value is that we can see the routing flow directly, without any extra abstraction.
Project structure
The example contains:
app-router.phpfor the router classconfig.inifor router and application configurationpage/for page view and page logic filesapi/v1/for API logic filesclass/for ordinary application classes
The flow
The entry script in example/01-test.php does the following:
- loads configuration
- creates a PSR-7 request
- creates a service container
- configures a
PathMatcher - loads the application router class
- handles redirects if a CSV file exists
- calls
route() - reads the resulting logic and view assemblies
- registers the logic stream wrapper
- loads each logic file and calls its
go()function
That is essentially the routing part of a framework laid out in one file.
Router callbacks in the example
The router has three callbacks:
api()
#[Any(name: "api-route", accept: "application/json,application/xml")]
This callback adds matching logic files from api/v1/ to the logic assembly.
page()
#[Get(name: "page-route", accept: "text/html,application/xhtml+xml")]
This callback adds matching PHP logic files from page/ and matching HTML view files from page/.
dynamicText()
#[Post(path: "/greet/@name", function: "greet", accept: "text/plain")]
This callback is part of the example project’s layout, but it is worth noting that callback path matching in BaseRouter is currently exact. Dynamic placeholder matching in this repository is handled by the path-matching layer described in Path matching and Dynamic path mapping.
Path matching in the example
The example’s PathMatcher filter uses:
BasicFileMatchfor direct file matchesMagicFileMatchfor_common,_headerand_footerstyle files
That combination is enough to build a request assembly for both nested pages and dynamic routes.
Dynamic path access
The example’s page logic reads values from DynamicPath, for example:
function go(DynamicPath $path) {
echo "SHOP ITEM: " . $path->get("itemName"), PHP_EOL;
}
This shows how placeholder values from the route can be injected into ordinary PHP logic.
Why this matters
This example is the clearest place to see the repository’s boundary:
- the router decides what belongs to the request
- the assemblies record the result
- another layer then loads the files and produces the response
That same separation is what allows WebEngine to use this library as a component.