PHP: Lezione 4 – mod_rewrite interpretare le url

Posted on novembre 21, 2007
Filed Under Appunti di Php | 3 Comments

Ebbene si’, con il mod_rewrite le url vengono interpretate non riscritte. E’ bene chiarire che il mod_rewrite non serve alla riscrittura delle URL quindi inutile che proviate ad attivare il modulo sperando di passare da /product.php?id=1 a /bambole-di-pezza.html perche’ il mod_rewrite non fa questo.
Altra cosa da chiarire: il mod_rewrite puo’ funzionare anche con windows. Funziona sia con il server Web Apache che con IIS ma visto che non e’ compito di questo corso spiegare come si configura un Web Server come IIS vi consiglio di leggervi http://www.isapirewrite.com o altri simili. Usando Apache la cosa e’ invece piu’ semplice basta creare il file .htaccess…ma i file che iniziano con il punto a windows non piacciono e allora ? Allora basta studiare un attimo il file di configurazione di Apache per capire che .htaccess e’ l’AccessFileName ossia il nome del file usato per riscrivere le url (e non solo!). Ma noi possiamo tranquillamente modificare la configurazione di Apache; ci bastera’ chiamarlo ad esempio htaccess et voila’ il nostro AccessFileName si chiamera’ d’ora in poi htaccess anche nei nostri virtualhost.

Fatte queste premesse non ci dilungheremo sul perche’ e’ necessario il mod_rewrite per sviluppare con PHP in maniera SEO oriented; ci basti sapere che /product.php?id=1 non ci dice un gran che mentre /bambole-di-pezza.html ci da chiaramente un’idea di cosa si tratti quindi inutile provare a realizzare il nostro sito senza il mod_rewrite. A quelli che storceranno il naso andando solo pensare che il server Web riceva un maggiore carico rispondiamo pure che andremo ad ottimizzare anche il carico di lavoro per il server quindi W il mod_rewrite!
Per attivare il mod_rewrite apriamo il file httpd.conf del nostro Apache e decommentiamo (togliere il # ) la riga: #LoadModule rewrite_module modules/mod_rewrite.so

Riavviamo quindi Apache per rendere effettivi i cambiamenti. Nel caso ci fossero errori esaminate il file error.log per capire cosa e’ andato storto.
Nelle vecchie versioni di Apache occorre decommentare la riga: #AddModule mod_rewrite.c

Visto che ci troviamo in Windows ed abbiamo cambiato l’AccessFileName creiamo nella cartella phpdir il file htaccess che ci permettera’ di leggere il file /bambole-di-pezza.html come se digitassimo /product.php?id=1
All’interno del file htaccess scriviamo:
RewriteEngine On
RewriteRule ^bambole-di-pezza\.html$ /product.php?id=1

Il backslash funziona da carattere di escape per far interpretare il . come carattere letterale e non come carattere speciale.
Creiamo quindi il file product.php ed inseriamo le seguenti righe:
<?php
echo(“Prodotto: “.$_GET[‘id’]);
?>

Salviamo ed usciamo e andiamo all’url: http://virtualphp.example.com/bambole-di-pezza.html se tutto e’ andato bene dovremo vedere a video: Prodotto: 1
Come vediamo siamo noi che andiamo all’url http://virtualphp.example.com/bambole-di-pezza.html e quindi saremo noi lato programmazione che dovremo creare gli url riscritti. Sara’ poi compito del mod_rewrite interpretarli.
Vi invito a studiarvi le variabili $_GET e $_POST e a farvi una stampa a video di $_SERVER con la direttiva:
print_r($_SERVER);

In breve ecco cosa accade quando il visitatore accedere all’url: http://virtualphp.example.com/bambole-di-pezza.html

Il visitatore interroga il nostro Apache Server il quale passa la palla al mod_rewrite che traduce l’url in http://virtualphp.example.com/product.php?id=1 ed invia l’output all’utente. Queste le variabili utilizzate:
La richiesta originale: $_SERVER[‘REQUEST_URI’] /bambole-di-pezza.html
Il nome del file dello script in esecuzione: $_SERVER[‘PHP_SELF’] /product.php
il parametro id della querystring: $_GET[‘id’] 1
La querystring dell’url riscritto: $_SERVER[‘QUERY_STRING’] id=1

Per utilizzare al meglio il mod_rewrite e’ consigliato studiarsi almeno le basi delle regexp (REGular EXPression). Un’ottimo inizio ci viene fornito dalla wikipedia.
Con le regular expression eviteremo di scrivere 100 regole per 100 prodotti ma potremo semplicemente utilizzare la seguente regola:
RewriteRule ^bambole/B([0-9]*)\.html$ /product.php?id=$1 [L]

Avremo:
bambole/B1.html –> product.php/id=1
bambole/B2.html –> product.php/id=2

Il primo elemendo della RewriteRule e’ l’espressione regolare che vogliamo riscrivere; il secondo argomento e’ l’url reale ed il terzo e’ la direttiva da utilizzare che puo’ essere:
R: Redirect
F: Proibito
G: Gone
P: Proxy
L: Ultima regola da leggere
NC: direttiva case-insensitive
S: skip the next rule.

Alcuni metacaratteri comunemente utilizzati nelle regexp sono:
^: l’inizio della linea. Solitamente e’ l’inizio dell’URL
.: corrisponde ad ogni singolo carattere
*: il char o l’espressione precedente puo’ essere ripetuta zero o piu’ volte.
+: il char o l’espressione precedente puo’ essere ripetuta una o piu’ volte.
?: il char o l’espressione precedente puo’ esser eripetuta zero o una volta.
{m,n}: il precedente char o espressione puo’ essere ripetuta tra m ed n volte con m<n numeri interi.
(): definiscono l’espressione da prendere. L’espressione tra parentesi puo’ essere letta come variabile.
[]: e’ usata per definire una classe di caratteri (Es.: [abcd]).
[^]: e’ simile a [] ma nella maniera negativa (ES.: [^abcd] significa matchare tutti i char tranne a,b,c,d.
$: Corrisponde alla fine della linea. Solitamente e’ la fine dell’url.
\: e’ usato come char di escape (Es.: \.)

Nel caso in cui si volessero riscrivere un url cosi’ fatto:
http://virtualphp.example.com/bambole/C1/P2.html

Potremo usare la seguente regola:
RewriteRule ^bambole/C([0-9]*)/P([0-9]*)\.html$ /product.php?cat=$1&id=$2 [L]

Il mood_rewrite pero’ non e’ ancora utile per i nostri scopi. Molto meglio se riuscissimo a riscrivere l’url cosi’ fatto:
http://virtualphp.example.com/bambole/pezza/cotone.html

Cio’ puo’ essere fatto in due modalita’:
1. Introducendo una colonna nella tabella dei prodotti a cui e’ associato un URL univoco per ogni prodotto possibilmente generato in fase di inserimento/importazione;

2. Inserendo nell’url oltre al nome della categoria e del record anche il relativo id, ossia:
http://virtualphp.example.com/bambole/pezza-C1/cotone-P2.html

Nell’ultimo caso la regola associata sara’ del tipo:
RewriteRule ^bambole/.*-C([0-9]+)/.*-P([0-9]+)\.html$ /product.php?cat=$1&id=$2 [L]

In tal caso pero’ la struttura e’ meno sicura meglio quindi la prima soluzione o, solitamente una soluzione ibrida che generi gli url in questo modo:
– a partire da un campo testuale importante che non possa risultare nullo creare l’url. Nel caso in cui l’url risulti gia’ “occupato” aggiungere il suffisso chiave primaria della nostra tabella.
Es.:
Supponiamo di avere la tabella prodotti cosi’ fatta:
id – chiave primaria (AUTO_INCREMENT)
nomeProdotto – NOT NULL
urlProdotto – NULL

Dovremo operare nel seguente modo:
– inserire il nuovo record nella tabella prodotto e prelevare l’id del nuovo prodotto
– pulire la stringa nomeProdotto da caratteri spuri;
– creare l’url desiderato (Ad es.: nomeProdotto)
– verificare se l’url + (.html) e’ gia’ presente:
– se non esiste vado ad inserire l’url generato + (.html) nel campo urlProdotto
– se l’url esiste vado ad inserire l’url generato + (-id.html) nel campo prodotto.

Semplice ed efficace. Ovviamente piu’ sara’ lungo nomeProdotto minore sara’ il caso in cui io abbia due url identici.
Lato SEO e’ bene sostituire alcuni caratteri con il vuoto e gli spazi con il “-“, quindi ad es. il nomeProdotto “Citta’ Grande” avra’ come url: “Citta-Grande.html”

Per fare cio’ potremo usare la seguente sintassi:
$charDel = ‘#[^-a-zA-Z0-9_ ]#‘;
$string = preg_replace($charDel, ‘’, $string);
$string = trim($string);
$string = preg_replace(‘#[-_ ]+#‘, ‘-‘, $string);

Un altro rewrite utile puo’ essere quello delle immagini che si puo’ ottenere con questa regola:
RewriteRule ^upload/.*-I([0-9]+)\.html$ /img/$1.jpg [L]

Se adesso avremo un html con la seguente riga:
<img src=”http://virtualphp.example.com/upload/Immagine-M5.jpg” alt=”Minnie” />

Verra’ mostrata a video l’immagine 5.jpg contenuta nella cartella img presente sulla root.

L’url rewriting non ci evita affatto il contenuto duplicato; vedremo nel seguito come far fronte a determinate situazioni.
Nel caso in cui alcune pagine dovessero cambiare url e’ bene fare uso del redirect 301 che indica ai motori di ricerca la nuova locazione della vecchia pagina senza che si perda nulla per l’utente che arriva direttamente dai motori.

Ah giusto…avevamo detto che ottimizzavamo il carico del Web Server…giusto e’ il caso di studiarsi il mod_gzip…ma in un futuro!

Tag:, , , , , , ,

Others Script adv

3 Responses to “PHP: Lezione 4 – mod_rewrite interpretare le url”

  1. beacon score on agosto 19th, 2008 17:53

    Very Nice Site! Thanx!

  2. Andrea on dicembre 15th, 2008 16:27

    Ciao, grazie per questo interessantissimo tutorial.
    Ho però un problema: su un sito sviluppato con joomla e mod_rewrite attivo, ho la necessità di recuperare le variabili _GET originali e provando ad utilizzare l’istruzione print_r($_SERVER) non trovo nulla dell’url originale ma solo i valori dopo la redirect…mi sai aiutare?

  3. Rino on giugno 30th, 2010 12:12

Leave a Reply