Pisaliśmy już prosty router poprzednio – teraz spróbujemy coś bardziej zaawansowanego i lepiej poukładanego. Zaczniemy od prostej metody pomocniczej.

Oto nasze ścieżki:

<?php 

$paths = [
    '/',
    'about/show',
    'home/view/',
    '/contact/info'
];

Jak widać, brakuje im spójnego formatu. Postarajmy się to naprawić:

class Router {

    public static function normalizePath($path){
        $path = trim($path, '/');
        $path = "/{$path}/";
        return $path;
    }
}

Trim z tak przekazanym argumentem usuwa znaki „/” po lewej i prawej stronie, ale nie w środku, jeśli występują. Później tylko te znaki dodajemy dla pewności.

Sprawdźmy, czy działa i nie ma problemów:

foreach($paths as $path){
    echo "$path => "  . Router::normalizePath($path);
    echo "<br>";
}

/*

/ => //
about/show => /about/show/
home/view/ => /home/view/
/contact/info => /contact/info/

*/

Problemem jest „/”. Po trimowaniu mamy tam pusty string „” wrzucony w //, stąd takie dziwne zachowanie. Regularne mogą nam tu pomóc i na zwykły „/” ścieżkę zamienić:

<?php 

$paths = [
    '/',
    'about/show',
    'home/view/',
    '/contact/info'
];

class Router {

    public static function normalizePath($path){

        $path = trim($path, '/');
        $path = "/{$path}/";
        $path = preg_replace('#[/]{2,}#', '/', $path);
        
        return $path;
    }
}

foreach($paths as $path){
    echo "$path => "  . Router::normalizePath($path);
    echo "<br>";
}

/*

/ => /
about/show => /about/show/
home/view/ => /home/view/
/contact/info => /contact/info/

*/

Zauważmy, że tam daliśmy 2 lub więcej slaszy, więc nieważne ile następujących po sobie ich mamy, metoda poradzi sobie:

<?php 

$paths = [
    '/',
    "/////////////",
    "/part1/part2/part3"
];

class Router {

    public static function normalizePath($path){

        $path = trim($path, '/');
        $path = "/{$path}/";
        $path = preg_replace('#[/]{2,}#', '/', $path);

        return $path;
    }
}

foreach($paths as $path){
    echo "$path => "  . Router::normalizePath($path);
    echo "<br>";
}

/*

/ => /
///////////// => /
/part1/part2/part3 => /part1/part2/part3/
*/

Pamiętajmy też, że trim, cóż, „trimuje” z lewej i prawej, tego co w środku nie usuwa:

echo trim('/', '/') . "<br>";
//''
echo trim("/////", "/") . "<br>";
//''
echo trim("//////////sth/sth///////", '/') . "<br>";
//sth/sth

Tak wyglądają segmenty, które potem wsadzamy między „/” oraz „/”, zaś jak mamy „//” (lub jeszcze więcej sleszy) to na „/” zamieniamy.