2011-12-09 26 views
15

Sé que puede agregar reglas en htaccess, pero veo que los frameworks PHP no hacen eso y de alguna manera usted todavía tiene URL bonitas. ¿Cómo lo hacen si el servidor no tiene conocimiento de las reglas de URL?Pretty URLs en frameworks PHP

He estado buscando Yii's url manager class pero no entiendo cómo lo hace.

+5

Ver mi respuesta [Cómo cambiar la apariencia de la URL desde dentro de un script PHP] (http://stackoverflow.com/questions/8392965/how-to-change-appearance-of-url-from-within-a- php-script/8392997 # 8392997) Lo que hace la mayoría del marco es redirigir todas las solicitudes a un archivo que maneja todo. – Ibu

Respuesta

15

Esto se hace generalmente mediante el enrutamiento de todas las solicitudes a un solo punto de entrada (un archivo que ejecuta código diferente en función de la solicitud) con una regla como:

# 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] 

Este archivo se compara la petición ($_SERVER["REQUEST_URI"]) en una lista de rutas: una asignación de un patrón que coincide con la solicitud a una acción del controlador (en aplicaciones MVC) u otra ruta de ejecución. Los marcos generalmente incluyen una ruta que puede inferir el controlador y la acción desde la propia solicitud, como una ruta de respaldo.

Un pequeño ejemplo simplificado:

<?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; 

En combinación con la primera configuración, se trata de un simple script que le permitirá utilizar las URL como domain.com/about. Espero que esto te ayude a dar sentido a lo que está sucediendo aquí.

+1

en su código se olvida: para agregar la url en los parámetros GET: 'RewriteRule (. *) Index.php? Url = $ 1 [QSA, L]' –

+1

Hola Olivier, no es realmente necesario pasar la url como un parámetro como está disponible en '$ _SERVER ['REQUEST_URI']'. – Ross

+0

¿Está seguro * de que no será la URL reescrita final (es decir, '$ _SERVER ['REQUEST_URI']' == 'index.php')? –