19

I know that you can add rules in htaccess, but I see that PHP frameworks don't do that and somehow you still have pretty URLs. How do they do that if the server is not aware of the URL rules?

I've been looking Yii's url manager class but I don't understand how it does it.

2

1 Answer 1

17

This is usually done by routing all requests to a single entry point (a file that executes different code based on the request) with a rule like:

# Redirect everything that doesn't match a directory or file to index.php RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule .* index.php [L] 

This file then compares the request ($_SERVER["REQUEST_URI"]) against a list of routes - a mapping of a pattern matching the request to a controller action (in MVC applications) or another path of execution. Frameworks often include a route that can infer the controller and action from the request itself, as a backup route.

A small, simplified example:

<?php // Define a couple of simple actions class Home { public function GET() { return 'Homepage'; } } class About { public function GET() { return 'About page'; } } // Mapping of request pattern (URL) to action classes (above) $routes = array( '/' => 'Home', '/about' => 'About' ); // Match the request to a route (find the first matching URL in routes) $request = '/' . trim($_SERVER['REQUEST_URI'], '/'); $route = null; foreach ($routes as $pattern => $class) { if ($pattern == $request) { $route = $class; break; } } // If no route matched, or class for route not found (404) if (is_null($route) || !class_exists($route)) { header('HTTP/1.1 404 Not Found'); echo 'Page not found'; exit(1); } // If method not found in action class, send a 405 (e.g. Home::POST()) if (!method_exists($route, $_SERVER["REQUEST_METHOD"])) { header('HTTP/1.1 405 Method not allowed'); echo 'Method not allowed'; exit(1); } // Otherwise, return the result of the action $action = new $route; $result = call_user_func(array($action, $_SERVER["REQUEST_METHOD"])); echo $result; 

Combined with the first configuration, this is a simple script that will allow you to use URLs like domain.com/about. Hope this helps you make sense of what's going on here.

Sign up to request clarification or add additional context in comments.

3 Comments

in your code you forget: to add the url in the GET params: RewriteRule (.*) index.php?url=$1 [QSA,L]
Hi Olivier, it's not really necessary to pass the url as a parameter as it's available in $_SERVER['REQUEST_URI'].
Are you sure that it won't be the final rewritten URL (i.e. $_SERVER['REQUEST_URI']==index.php)?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.