Search code examples
phproutes

Routing does only work locally with self written PHP routing method


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();
}

Solution

  • 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.