I wrote a project without an existing framework which I now want to deploy on a Microsoft IIS. Falsely I thought this would be done in a few minutes, but I had to find out that my routing doesn't work on the IIS, even though it's working perfectly on the PHP built in web server.
Here's my routing function:
function router(string $route, mixed $callback) :bool {
$url_parts = explode('/', trim($_SERVER['REQUEST_URI'], '/'));
$requested_route = implode('/', $url_parts);
$route_regex = preg_replace('/:[^\/]+/', '([^\/]+)', $route);
if (preg_match("~^$route_regex$~", $requested_route, $matches)) {
call_user_func_array($callback, array_slice($matches, 1));
return true;
}
return false;
}
Here's how I call the function:
$routeFound = router('', static function() {
$pagesInstance = new Pages();
$pagesInstance->login();
});
$routeFound = router('login', static function() {
$pagesInstance = new Pages();
$pagesInstance->login();
}) || $routeFound;
if (!$routeFound) {
header("HTTP/1.0 404 Not Found");
echo "404 Not Found";
exit();
}
Here's the web.config I tried:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="RouteAllThroughIndex" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
</conditions>
<action type="Rewrite" url="index.php/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
The folder structure:
project
assets
controllers
helpers
languages
models
system
classes
helpers
views
index.php
I'd be very happy if someone could help me with this.
I expect the code to execute the functions which are defined through the routes, but I always get the result of the following block:
if (!$routeFound) {
header("HTTP/1.0 404 Not Found");
echo "404 Not Found";
exit();
}
Luckily I found the answer while staring at it.
My routing function doesn't work with subfolders, which means http://localhost:8000/
was working fine, because the route would always be /login
, but http://some-url.com/project/
doesn't work, because the route would be project/login
.
Just added an array_shift($url_parts)
to the routing function and now it works.