Skip to main content

Request URI parser

function parse_request_uri() {
    $parts = [];

    if (array_key_exists('REQUEST_URI', $_SERVER)) {
        $request_path = explode('?', $_SERVER['REQUEST_URI']);

        $parts['base'] = rtrim(dirname($_SERVER['SCRIPT_NAME']), '\/');
        $parts['path'] = substr(urldecode($request_path[0]), strlen($parts['base']) + 1);

        if ($parts['path'] === basename($_SERVER['PHP_SELF'])) {
            $parts['path'] = '/';
        } elseif ($parts['path'] === false) {
            $parts['path'] = '/';
        }

        $parts['path_parts'] = [];

        if ($parts['path'] !== '/') {
            $parts['path_parts'] = explode('/', $parts['path']);
        }

        if (isset($request_path[1])) {
            $parts['query_string'] = urldecode($request_path[1]);
            parse_str($parts['query_string'], $parts['query_vars']);
        }
    }

    return $parts;
}

Ideas?

Using following .htaccess:

Options +FollowSymLinks
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]

Examples:

URI Request: http://url/hello/world?hello=world

Results:

array(5) { 
  ["base"]=> string(0) "" 
  ["path"]=> string(11) "hello/world" 
  ["path_parts"]=> array(2) { 
    [0]=> string(5) "hello" 
    [1]=> string(5) "world" 
  } 
  ["query_string"]=> string(11) "hello=world" 
  ["query_vars"]=> array(1) { 
    ["hello"]=> string(5) "world" 
  } 
}

URI Request: http://url/index.php/hello/world?hello=world

Results:

array(5) { 
  ["base"]=> string(0) "" 
  ["path"]=> string(21) "index.php/hello/world" 
  ["path_parts"]=> array(3) { 
    [0]=> string(9) "index.php" 
    [1]=> string(5) "hello" [2]=> string(5) "world" 
  } 
  ["query_string"]=> string(11) "hello=world" 
  ["query_vars"]=> array(1) { 
    ["hello"]=> string(5) "world" 
  } 
}

Not sure if index.php actually should show up there as it is the file name the function is called in?

URI Request: http://url/index.php/hello/world/?hello=world

Results:

array(5) { 
  ["base"]=> string(0) "" 
  ["path"]=> string(22) "index.php/hello/world/" 
  ["path_parts"]=> array(4) { 
    [0]=> string(9) "index.php" 
    [1]=> string(5) "hello" 
    [2]=> string(5) "world" 
    [3]=> string(0) ""
  } 
  ["query_string"]=> string(11) "hello=world" 
  ["query_vars"]=> array(1) { 
    ["hello"]=> string(5) "world" 
  } 
}

The fourth element in parts should probably not be there?

Do you have any ideas on how I can improve the code (make it shorter) and remove the obvious flaws mentioned above or any other ideas you have?