-
Notifications
You must be signed in to change notification settings - Fork 1
Basic routing
Index > HTTP routing > Basic routing
SnooPHP\Http\Router is the class that we use to perform HTTP routing.
To create a router simply create a new object:
$router = new Router();Routers must be registered with the application using the global function register_router():
$router = register_router(new Router());The router is merely a container for one or more Route objects. A route is defined by an HTTP method (GET or POST for example), an URL and an action to perform on match. To define a GET route we call Router::get() on our Router object:
$router->get("/home", function() {
echo "Hello world!"; // Sorry, I had to put it somewhere
});This route will output Hello world! when the folder /home is requested.
If we want to respond to a form submission we can create a POST route with Router::post() method:
$router->post("/login", function() {
echo "Logged in!";
});Similar methods are available for PUT, DELETE and OPTIONS requests.
The Request processed by the router is saved in a SnooPHP\Http\Request object that can be accessed with the static method Request::current(). The current request is also passed as the first parameter to the route action:
$router->get("/home", function(Request $request) {});The Request object exposes a series of methods and properties to retrieve request inputs, request headers and additional informations:
-
Request::input(string|null $input = null, mixed $default = null)is used to retrieve request input. If the name of the input is provided, the corresponding value is returned, otherwise an array with all the inputs is returned. If the specified input is not found,$defaultis returned (nullby default); -
Request::file(string|null $file = null)returns the specified file (nullif not found) or an array of uploaded files; -
Request::header(string|null $header = null])returns the specified header value (nullif not found) or an array of all the request headers; -
Request::url()returns the requested URL; -
Request::method()returns the request method as an uppercase string; -
Request::time(bool $timestamp = false)returns the time of the request as an ISO string, or as a UNIX timestamp if$timestamp == true
Here's an example of a login route:
$router->post("/login", function(Request $request) {
$username = $request->input("username");
$password = $request->input("password");
$stayLogged = $request->input("stay_logged", false);
// Check login and start session
if (Auth::login($username, $password, $stayLogged))
echo "Logged in!";
else
echo "Wrong username or password!";
});While you can use echo and other built-in functions like header() and http_response_code() to respond to a request, the recommended way is to return a SnooPHP\Http\Response object instead:
$router->post("/home", function(Request $request) {
return new Response("Hello world!", 200);
});A Response object takes a content, an http code and an array of headers.
The Response class allows you to quickly build different responses using one of this static methods:
-
Response::json(string|array|object $content, int $code = 200)converts your array/object in a JSON string and appends aContent-Type: application/jsonheader to the response; -
Response::resource(string $file, string|null $type = null, bool $evaluatePhp = false)search for$filein the/resourcefolder and returns its content. You can specify the content MIME type or let the application decide the most appropriate one. If$evaluatePhp == truethe eventual PHP code inside the file is executed and the final content is returned. -
Response::abort(int $code, string|array|object $content = "")doesn't require a return statement, but rather throws aSnooPHP\Http\AbortRouteExceptionthat aborts routing immediately.
Here's the same login example using Response:
$router->post("/login", function(Request $request) {
$username = $request->input("username");
$password = $request->input("password");
$stayLogged = $request->input("stay_logged", false);
// Check login and start session
if (Auth::login($username, $password, $stayLogged))
return Response::json(["status" => "OK", "description" => "logged in"]);
else
Response::abort(403, ["status" => "ERROR", "description" => "username or password incorrect"]);
});You can also return false. In this case, following routes have a possibility to match the request.
A router has a base, which by default is /. You can specify a different base in the constructor like this:
$router = new Router("/base");All routes created from this router will inherit this base:
$router->get("home", function() {}); // matches 'GET /base/home'You can define and register multiple routers with different bases, just keep in mind that when multiple routes matches the request, only the action of the first one is executed, so the order in which you declare your routes matters!
When no route matches the request, an "error action" is executed. You can specify the error action with Router::error():
$router->error(function(Request $request) {
// Here you cannot use Response::abort()
return new Response("not found", 404);
});In case of multiple routers, the error action of the router with the appropriate base is executed: for example, given two routers
Router("/abc)"andRouter("/123"), for the URL/abc/def/123the most appropriate router is the former.
It is possible to specify a set of default headers, appended to all responses generated by this router:
$router->defaultHeader([
"My-Custom-Header" => "value",
"Access-Control-Allow-Origin" => "*"
]);If you want a specific route to ignore this default headers you can set the response property $ignoreDefaultHeaders = true:
$router->error(function(Request $request) {
$res = new Response("not found", 404);
$res->ignoreDefaultHeaders = true;
return $res;
});