Rewriting dispatch method
The array_search will iterate over every element in $this-&gt;routes. That's not scalable. It would be better to reorganize $this-&gt;routes so that you can lookup keys more directly, so that your code will work like this:

if (isset($this-&gt;routes[$this-&gt;reqUri])) {
    $key = $this-&gt;routes[$this-&gt;reqUri];
    // ...
}


In this arrangement, the lookup should be in \$O(1)\$ time or close, even with large number of routes.



Do you really need the !== false here?


if ($key !== false) {



Can't it be simply:

if ($key) {




In the innermost if, since you return in both the if and the else, you could move the return statement outside:

if (isset($this-&gt;methods[$key])) {
    if ($this-&gt;methods[$key] === $this-&gt;reqMethod) {
        call_user_func($this-&gt;callables[$key]);
    } else {
        $this-&gt;defaultCallable();
    }
    return;
}




In terms of readability, I find it slightly better this way:

if ($key) {
    if (isset($this-&gt;methods[$key])) {
        if ($this-&gt;methods[$key] === $this-&gt;reqMethod) {
            call_user_func($this-&gt;callables[$key]);
            return;
        }
    } else {
        call_user_func($this-&gt;callables[$key]);
        return;
    }
}

$this-&gt;defaultCallable();


That is, the $this-&gt;defaultCallable() call appears only once instead of twice, everything else still being the same.