Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have developed a new router after having learnt a lot from my previous attempts and I will be using this in sites I make from now on.

In a previous question, the issue of REQUEST_URI being too inflexible made me wonder if I could make adjustments to allow it to route $_POST and $_GET requests too?

Please let me know what you think and how it could be improved as I am still learning:

class Router {

public $offset = 9 ; // Adjust according to subdir length.
public $start_page = 'Index' ; // Change to your home/default page.
private $classAliases = array(
    'pretty-url' => 'UglyClassName',
) ;

private $methodAliases = array(
    'pretty-method' => 'uglyMethodName',
) ;

function __construct()
{
    $url = substr(rtrim($_SERVER['REQUEST_URI'], '/'), $this->offset) ;

    $command = explode('/', $url, 3) ;

    if(isset($command[0]))
    {
        $class = ucfirst($this->autoMap($command[0]), $this->classAliases) ;
    }

    if(class_exists($class) && preg_match('/[^A-Za-z0-9]/', $class) == false)
    {
        $controller = new $class ;

        if($method = (isset($command[1]) ? $command[1] : NULL))
        {
            $method = (strstr($method, '?') ? substr($url, 0, strrpos($method, '?')) : $method) ;
            $method = $this->autoMap($method, $this->methodAliases) ;
            if(method_exists($class, $method) && preg_match('/[^A-Za-z0-9]/', $method) == false)
            {
                $params = array() ;
                if(stristr($url, '?')) // Parameters passed the conventional way...
                {
                    $queryString = substr($url, strrpos($url, '?')+1) ;
                    parse_str($queryString, $params) ;
                }
                elseif(isset($command[2])) // ...or the clean URL way.
                {
                    $params = explode('/', $command[2]) ;
                }
                call_user_func_array(array($controller, $method), $params) ;
            }
            elseif($method)
            {
                $this->throwError('Method '.$method.' does not exist.') ;
            }
        } else { // Default index method.
            if(method_exists($class, 'index'))
            {
                $controller->index() ;
            } else {
                $this->throwError('Class '.$class.' has no index method.') ;
            }
        }
    }
    elseif(!$class)
    {
        $controller = new $this->start_page ;
        $controller->index() ;
    } else {
        $this->throwError('Class '.$class.' does not exist.') ;
    }
}

private function throwError($e)
{
    if(isset($_SERVER['HTTP_X_REQUESTED_WITH'])) // Ajax request...
    {
        echo $e ;
    } else { // ...or normal request.
        new Error($e) ;
    }
}

private function autoMap($alias, $routes)
{
    if(array_key_exists($alias, $routes))
    {
        return $routes[$alias] ;
    }
    return $alias ;
}

}
share|improve this question
add comment

1 Answer

Where you have: $class = ucfirst($this->autoMap($command[0]), $this->classAliases);

I think it should be: $class = ucfirst($this->autoMap($command[0], $this->classAliases));

The closing ')' is in the wrong place. Besides that I like your router, maybe it would be even better if it had a module control (so you could have something like: module/controller/method). This way you can have separated modules for admin, debug, default, etc.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.