2009-04-23 7 views
8

È ovviamente utile fornire agli utenti URL amichevoli per i loro contenuti sul tuo sito. Ma come meglio farlo? Ci sono molti vantaggi in qualcosa come foo.com/users/alice, soprattutto che non stai ingombrando il tuo spazio dei nomi di root. Ma penso che la semplicità per gli utenti sia al di sopra di tutto questo. Molti grandi siti sembrano essere d'accordo (mi viene in mente un messaggio di amicizia, delizioso e flickr) e questa domanda riguarda il modo in cui farlo sul lato server.foo.com/alice vs. foo.com/users/alice

Supponiamo che l'URL vero per alice sia foo.com/userpage?user=alice e che se qualcuno prova a navigare su una pagina utente inesistente (diciamo foo.com/bob) deve raggiungere foo.com/createnew ? user = bob.

L'utente ovviamente non dovrebbe mai vedere i brutti URL "reali" sopra, solo foo.com/alice o foo.com/bob. E si noti che lo spazio dei nomi di root è condiviso. Ad esempio, foo.com/help non deve essere tradotto in foo.com/userpage?user=help.

Presumibilmente sto chiedendo alcune semplici regole mod_rewrite, ma forse c'è un approccio completamente diverso a questo che non sto pensando. In ogni caso, ho pensato che sarebbe stato utile registrare una soluzione definitiva o "best practice" a questa domanda comune.

PS: Sentitevi liberi di commentare i meriti di altre alternative come alice.foo.com o users.foo.com/alice.

PPS: Penso di aver visto questo problema discusso in altre domande, ma sembra essere difficile da cercare. Puntatori benvenuti! Oltre a parole chiave aggiuntive per renderlo più ricercabile, ovviamente. Parole chiave: userspace, spazio dei nomi globale, spazio dei nomi URL.

risposta

3

Le seguenti regole di riscrittura di un URL del modulo foo.com/bar per foo.com/userpage?user=bar~~V~~singular~~3rd subordinata bar non già di essere un file o una directory sul server. Inserire il seguente nel file .htaccess:

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

Come nella risposta di Alex, lo script pagina utente dovrebbe reindirizzare CreateNew se l'utente non esiste:

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

(come dice Knuth, fate attenzione ai bug in il codice di cui sopra - l'ho solo dimostrato corretto, non provato. Aggiornerò questa risposta quando ho effettivamente confermato che funziona.) PS: CONFERMATO!

+0

Spero che funzioni! Ricorda che dovrai codificare una funzione user_exists()! – alex

5

Direi che dipende da come il tuo sito è centrato sull'utente.

Siti come myspace sono http://www.myspace.com/jim/ perché il sito ruota interamente attorno all'utente.

Un sito blog o notizia, tuttavia, dove è possibile registrarsi, ma non è importante o obbligatoria potrebbero beneficiare di

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

ne pensi se stai facendo un sito web con gli utenti si potrebbe beneficiano del pattern di progettazione MVC, o almeno di un framework MVC popolare che utilizza un router per dirigere gli URI?

Se l'URI è passato attraverso un router e quindi è stato inviato a UsersController, è possibile decidere di mostrare il profilo dell'utente o di dirigerlo per creare tale utente. Non avresti bisogno di scherzare con mod_rewrite eccetto per fare una regola che indirizza tutte le richieste a file non esistenti su index.php (o qualunque sia l'impostazione predefinita della tua lingua lato server)

Se si desidera utilizzare mod_rewrite, provare queste regole

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

si prega di notare il Carat leader come suggerito da Gumbo, in modo che corrisponda solo/utenti/solo il TLD.

Ciò corrisponde a qualsiasi cosa come foo.com/users/bob con una barra finale opzionale. È case insensitive e sarà l'ultima regola applicata.

Se la richiesta arriva e $ _GET [ 'user'] non esiste nel vostro DB, si potrebbe provare qualcosa di simile

$user = $_GET['user']; 

if (!user_exists($user)) { 

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

} 

Poi sulla pagina createnew, semplicemente fare qualcosa di simile

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

Questo riempirà il nome utente automaticamente con il nome utente con cui hanno provato ad accedere a un profilo.

Se vuoi sapere di più su PHP e MVC, provare una ricerca su Google o porre una domanda qui su Stack Overflow.

+1

Grazie, molto utile! Ottimo punto su MVC. Per ora questo è solo php hackerato quindi le regole mod_rewrite sarebbero molto utili a breve termine. Penso che il tuo suggerimento sia un modo migliore per farlo a lungo termine. – dreeves

+0

Va bene, vedrò cosa posso fare per regole mod_rewrite – alex

+0

Se si voleva fare tutto foo.com/alice andare pagina utente, che ci sia bisogno di specificare che cosa non dovrebbe andare lì (come su | contatto | aiuto) o avresti bisogno di usare una sottodirectory falso come/utenti/ – alex