2009-04-23 5 views
8

Por supuesto, es agradable dar a los usuarios URL amigables para su contenido en su sitio. Pero, ¿cuál es la mejor manera de hacerlo? Hay muchas ventajas en algo como foo.com/users/alice, y lo más importante es que no está saturando el espacio de nombres raíz. Pero creo que la simplicidad para los usuarios supera todo eso. Muchos sitios grandes parecen estar de acuerdo (me vienen a la mente los siguientes: friendfeed, delicious y flickr) y esta pregunta es acerca de cómo lograr eso en el lado del servidor.foo.com/alice vs. foo.com/users/alice

Supongamos que la URL real para alice es foo.com/userpage?user=alice y que si alguien intenta navegar a una página de usuario inexistente (digamos foo.com/bob) debería llegar a foo.com/createnew ? usuario = bob.

El usuario, por supuesto, nunca debería ver las feas URL "reales" anteriores, solo foo.com/alice o foo.com/bob. Y tenga en cuenta que el espacio de nombres raíz se comparte. Por ejemplo, foo.com/help no debe traducirse a foo.com/userpage?user=help.

Presumiblemente estoy pidiendo algunas reglas simples de mod_rewrite, pero tal vez hay un enfoque completamente diferente de esto en el que no estoy pensando. En cualquier caso, pensé que sería bueno registrar una solución definitiva o de "mejores prácticas" para esta pregunta común.

PD: Siéntase libre de comentar sobre los méritos de otras alternativas como alice.foo.com o users.foo.com/alice.

PPS: Creo que he visto este tema debatido en otras cuestiones, pero parece ser difícil de buscar. ¡Los indicadores son bienvenidos! Además de palabras clave adicionales para que esto sea más fácil de buscar, por supuesto. Palabras clave: espacio de usuario, espacio de nombres global, espacio de nombres URL.

Respuesta

3

Las reglas siguientes vuelven a escribir una URL del formulario foo.com/bar a foo.com/userpage?user=bar condicional en la barra que todavía no es un archivo o directorio en el servidor. Poner el siguiente en .htaccess:

<IfModule mod_rewrite.c> 
RewriteEngine On 
RewriteBase/
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule ^([^/]+)/?$ userpage?user=$1 [NC,L] 
</IfModule> 

Al igual que en la respuesta de Alex, el guión página de usuario debe redirigir a createnew si el usuario no existe:

$user = $_GET['user']; 
if (!user_exists($user)) { 
    header('Location: createnew?user=' . urlencode($user)); 
} 

(Como dice Knuth, cuidado con los errores en el código anterior: solo he demostrado que es correcto, no lo intenté. Actualizaré esta respuesta cuando realmente haya confirmado que funciona.) PD: ¡CONFIRMADO!

+0

¡Espero que funcione! ¡Recuerde que tendrá que codificar una función user_exists()! – alex

5

Yo diría que depende de qué tan centrado esté el usuario en su sitio.

Los sitios como myspace son http://www.myspace.com/jim/ porque el sitio gira completamente en torno al usuario.

Un sitio de blogs o noticias, sin embargo, donde se puede registrar, pero no es importante ni obligatoria podrían beneficiarse de

http://www.news.com.au/users/jim/

¿Cree que si está haciendo una página web con los usuarios que podría se benefician del patrón de diseño MVC, o al menos un marco MVC popular que utiliza un enrutador para dirigir URIs?

Si ese URI vino a través de un enrutador y luego se envió al UsersController, puede decidir mostrar el perfil del usuario o indicarle que cree ese usuario. No necesitaría perder el tiempo con mod_rewrite excepto para hacer una regla que dirija todas las solicitudes a archivos no existentes a index.php (o cualquiera que sea el idioma predeterminado del lado del servidor)

Si desea usar mod_rewrite, tratar estas reglas

RewriteEngine On 
RewriteCond %{REQUEST_URI} !(home|contact|about) [NC] // this line may be incorrect 
RewriteRule ^/users/([^/]+)/?$ userpage?user=$1 [NC,L] 

Tenga en cuenta el principal quilates como sugiere Gumbo, por lo que sólo coincide/usuarios/de sólo el dominio de nivel superior.

Eso coincidirá con algo como foo.com/users/bob con una barra inclinada opcional. No distingue entre mayúsculas y minúsculas y será la última regla aplicada.

Si la petición llega y los $ _GET [ 'usuario'] no existe en su base de datos, usted podría intentar algo como esto

$user = $_GET['user']; 

if (!user_exists($user)) { 

    header('Location: createnew?user=' . urlencode($user)); 
    exit(); 

} 

A continuación, en la página createnew, sólo tiene que hacer algo como esto

<input type="text" name="username" value="<?php echo htmlspecialchars(urldecode($_GET['user'])); ?>" /> 

Eso completará el nombre de usuario automáticamente con el nombre de usuario con el que trataron de acceder.

Si desea obtener más información acerca de PHP y MVC, intente realizar una búsqueda en Google o haga una pregunta aquí en Stack Overflow.

+1

¡Gracias, muy útiles! Gran punto acerca de MVC. Por ahora, esto es solo piratear php, por lo que las reglas de mod_rewrite serían muy útiles a corto plazo. Creo que su sugerencia es una mejor manera de hacerlo a largo plazo. – dreeves

+0

Bien, veré lo que puedo hacer sobre las reglas de mod_rewrite – alex

+0

Si quiere hacer que todas las páginas de usuario de foo.com/alice vayan, debe especificar lo que no debe ir allí (como sobre | contacto | ayuda) o necesitarías usar un subdirectorio falso como/users/ – alex

Cuestiones relacionadas