I am trying to create simple Router in PHP and I can't figure out why its no redirecting corectly.
So the way my setup works is I have 3 routes
- the home route "/"
- the user route "/user"
- the user with id route "/user?id={[0-9]}"
When I redirect to "/" route this is what gets printed.
/ Path / traversed
However I want this to be printed
/ Succesfuly navigated to / Path / traversed
However none of this works for any of the other paths. This is what I get when I redirect to "/user"
/user Not Found
And this is what I want to be rendered.
/user Succesfuly navigated to /user Path /user traversed
So this is my script for Router.php
<?php
class Router{
public function get($route, $callback){
$path = $this->getPath(); //GET PATH for ex. /users/user
$query = $this->getQuery(); //GET QUERY for ex. ?id=15
print($_SERVER['REQUEST_URI']);
echo " ";
//IF USER IS NAVIGATING TO ROUTE THAT DOESN'T EXIST PRINT "NOT FOUND"
if($path != $route){
$this->notFound();
}
if($path == $route){
//IF CALLBACK IS A STRING DO SOMETHING WITH IT
if(is_string($callback)){
echo "Succesfuly navigated to {$route}";
exit();
}
//EXECUTE CALLBACK FUNCTION
echo call_user_func($callback);
exit();
}
}
//GET PATH FROM URI
private function getPath(){
$path = $_SERVER['REQUEST_URI'] ?? '/';
$paramPosition = strpos($path, "?");
if($paramPosition === false){
return $path;
}
$path = substr($path, 0, $paramPosition);
return $path;
}
//GET QUERY STRING ?id=15
private function getQuery(){
$path = $_GET;
if(count($path) == 1){
return $path;
}
return $path;
}
//404 TEXT
private function notFound(){
http_response_code(404);
echo "Not Found";
exit();
}
}
?>
any this is my index.php
<?php
include_once './core/Router.php';
$router = new Router();
$router->get("/", function() {
echo "Path / traversed";
});
$router->get("/user", function() {
echo "Path /user traversed";
});
$router->get("/user?id={[0-9]}", function(){
echo "Path /user?id={[0-9]} traversed";
});
?>
CodePudding user response:
There are two problems I can see with this code:
1. "Not found" messages for routes other than /
The reason this is happening is because you are exit()
ing in the notFound
method. You check the / route first, it doesn't match, it outputs "Not Found", then exits.
What you can do instead is remove the exit()
and return from get
when not found:
//IF USER IS NAVIGATING TO ROUTE THAT DOESN'T EXIST PRINT "NOT FOUND"
if($path != $route){
$this->notFound();
return;
}
2. "Successfully navigated to" not appearing
This happening because you are checking for is_string
, however your callbacks are functions so this condition will never be true. You can change the condition to is_callable
:
//IF CALLBACK IS A STRING DO SOMETHING WITH IT
if(is_callable($callback)){
echo "Succesfuly navigated to {$route}";
exit();
}