2012-02-08 20 views
8

Ho un nuovo sito Web (ne sto costruendo uno proprio ora) e voglio assicurarmi di farlo correttamente e non riprogettarlo dopo 1 mese.apache .htaccess regola con prestazioni di pagine dinamiche (php)

così ho pagine come:

/candy 
/candy/chocolate 
/drink 
/drink/beer 

così guardo su StackOverflow su come posso fare questo e ho trovato:

RewriteRule ^([a-z]+)/([a-z]+)/?$ index.php?category=$1&page=$2 [NC,L] 

ora, questo funzionerà ma la mia domanda è circa l'esecuzione . ovviamente il $ _GET [categoria] sarà il nome e la pagina sarà il cioccolato per esempio.

ora quando faccio la mia domanda farò:

$sql = "SELECT myfields FROM mytable WHERE name = '" . $_GET['category'] . "'"; 

ora, sarebbe meglio se io uso la chiave primaria che è un INT. se sì, cosa posso fare nel mio .htaccess per fare questo?

+2

Se il nome è univoco, non importa. Se il nome non è unico, sei nella merda. –

+2

@bianca: ti dispiacerebbe URL come lo stackoverflow:/id/category/page? come:/123/caramelle/cioccolato/che la chiave di caramelle e cioccolato è unica e 123 è l'ultima pagina in questo caso ID cioccolato? –

+0

preferirei non da allora, ma se è l'unica opzione, immagino di sì. – Bianca

risposta

7

Purtroppo utilizzando un nome e convertirlo in un ID univoco potrebbe richiedere più tempo per l'esecuzione rispetto alla creazione di un indice sul nome stesso.

Ecco cosa vi consiglio in base agli URL avete:

Aggiungi un indice al nome della pagina

ALTER TABLE `mytable` ADD key indexname (columnname); 

esempio:

ALTER TABLE `page` ADD key pagename (name); 

Ora, perché la la struttura è diversa /candy rispetto a /candy/chocolate, presumo tu abbia una sorta di struttura come una pagina principale con Lista (/ caramelle) e elenco specifico (/ candychocolate) quindi in questo caso è possibile utilizzare questo:

RewriteRule ^([a-z]+)/?$ index.php?category=$1&page=list [NC,L] 
RewriteRule ^([a-z]+)/([a-z]+)/?$ index.php?category=$1&page=$2 [NC,L] 

allora si può semplicemente interrogare la categoria e la pagina utilizzando il campo indicizzato. Questo sarà veloce (ovviamente non veloce come un INT ma ancora veloce).

Per la prima query che si può fare:

$name = addslahes($name); 
SELECT fields FROM category WHERE category = '$name'; 

e quando si ottiene una pagina è possibile utilizzare:

$categoryname = addslahes($categoryname); 
$pagename = addslahes($pagename); 
SELECT fields FROM page LEFT JOIN category ON (page.categoryid = category.id) WHERE page = '$pagename' AND category = '$categoryname'; 

questo modo, utilizzando sia categoria e pagina, eviterete pagina non trovato (404).

0

L'identificativo utilizzato nell'URL deve essere univoco e avere un indice di database. Se sia l'ID che il nome della categoria sono univoci e indicizzati, è altrettanto efficace per le prestazioni, ma raccomanderei di usare il nome poiché è più intuitivo e descrittivo rispetto a un ID interno, che diventa particolarmente importante quando un URL è visualizzato da qualche parte senza molto contesto aggiuntivo (ad esempio, example.org/1 vs. example.org/shoes stampato su un giornale). In caso contrario, utilizzare ID e modificare la regola di riscrittura a: (. Btw, \d+ dovrebbe essere utilizzato anche per page se è numerico)

RewriteRule ^(\d+)/([a-z]+)/?$ index.php?category=$1&page=$2 [NC,L] 

3

Basta assicurarsi che il database ha un index per la riga del nome. Ciò renderà la ricerca veloce quanto l'utilizzo di una chiave primaria intera.

Utilizzare qualcosa come CREATE INDEX name ON mytable Penso, ma farlo tramite phpmyadmin è molto più semplice.

proteggere anche lo script da iniezione SQL utilizzando addslashes

$sql = "SELECT myfields FROM mytable WHERE name = '" . addslashes($_GET['category']) . "'"; 
+0

"SELECT ... FROM ... WHERE name = '". $ _GET ['categoria']. La parte "" è certamente più degna di menzionare rispetto alla domanda originale stessa! _Please_, proteggi il tuo codice da SQL injection, _do_ _non_ basta inserire l'input dell'utente nelle tue query SQL. Puoi aggiungere più protezione selezionando prima tutti i nomi di categoria dal DB e poi controllando se '$ _GET ['category']' è un nome di categoria noto con qualcosa come 'array_key_exists'. – hijarian

+0

@hijarian Non vedo come sia più sicuro di addslashes. Non c'è modo di iniettare codice in entrambi i modi, e addslashes è molto più breve. Alcune persone suggeriscono di utilizzare mysql_real_escape_string, ma ciò conta solo se si usa un set di caratteri diverso da ISO-8859-1 o UTF-8. – Gerben

Problemi correlati