Script PHP per generare redirect 301 di htaccess

Script PHP per generare redirect 301 di htaccess

Quando si aggiorna un sito web può essere necessario mappare gli indirizzi del vecchi sito con quelli del nuovo sito. Il sistema più usato, ed il più corretto, è quello di creare i redirect di tipo 301: ovvero configurare il web server in maniera tale che gli utenti siano reindirizzati verso le nuove pagine.

Da un punto di vista SEO, gestire correttamente i redirect è fondamentale se si vuole ottimizzare al meglio la migrazione di un sito web.

Esistono già decine e decine di guide, esempi e manuali su come configurare i redirect. Quindi in questo articolo non verrà spiegato in dettaglio il loro funzionamento, ma verrà illustrato un esempio di script PHP utile per la generazione automatica delle regole per il web server Apache da inserire nel file .htaccess.

Lo script presentato è da considerarsi come una bozza che si può riutilizzare ed adattare alle proprie esigenze.

Per questo motivo, ad esempio, l'elenco dei vecchi indirizzi e quello dei nuovi indirizzi sono specificati in due array distinti (attenzione all'ordinamento ed al numero), ma con poche modifiche al codice è possibile rendere lo script più elegante.

Il problema del redirect di URL con parametri

Gli indirizzi dei siti web potrebbero contenere dei parametri (query string), pertanto le regole di riscrittura devono tener conto di ciascuno di essi.

Nel caso in cui non ci siano parametri, infatti, la forma della regola è piuttosto semplice. Eccone un esempio:

RewriteRule ^vecchio-indirizzo.html$ /nuovo-indirizzo.html [R=301,L]

Mentre se abbiamo uno o più parametri bisogna indicarli uno ad uno. Nell'esempio seguente si crea un redirect dalla pagina

index.php?arg1=param1&arg2=param2&arg3=param3

ad una pagina priva di parametri:

RewriteCond %{QUERY_STRING} (^)arg1=param1(.*$)
RewriteCond %{QUERY_STRING} (.*)arg2=param2(.*$)
RewriteCond %{QUERY_STRING} (.*)arg3=param3($)
RewriteRule ^index.php /indirizzo-destinazione.html? [R=301,L]

Oppure si può usare una forma più compatta così:

RewriteCond %{QUERY_STRING} (^)arg1=param1&arg2=param2&arg3=param3($)
RewriteRule ^index.php /indirizzo-destinazione.html? [R=301,L]

Con PHP possiamo facilmente ciclare l'elenco di indirizzi, estrarre i parametri dai percorsi e quindi generare le regole per htaccess.

Esempio di script PHP per generare le regole 301 per htaccess

Ecco un esempio di codice PHP molto semplice:

$domain = 'http://www.example.com/';

$url_old = array(
  'http://www.example.com/simple-url.html',
  'http://www.example.com/directory/simple-url.html',
  'http://www.example.com/page.asp?arg1=param1',
  'http://www.example.com/page.asp?arg1=param1&arg2=param2',
  'http://www.example.com/page.asp?arg1=param1&arg2=param2&arg3=param3',
  'http://www.example.com/directory/page.asp?arg1=param1',
  'http://www.example.com/directory/page.asp?arg1=param1&arg2=param2',
  'http://www.example.com/directory/page.asp?arg1=param1&arg2=param2&arg3=param3'
);

$url_new = array(
  '/destination1.html',
  '/destination2.html',
  '/destination3.html',
  '/destination4.html',
  '/destination5.html',
  '/destination6.html',
  '/destination7.html',
  '/destination8.html',
);

foreach($url_old as $key => $url_old_item) {
  $path = str_replace($domain, '', $url_old_item);
  if (strpos($path, '?')) {
    $filename = strstr($path, '?', true);
    $paramstring = substr($path, strpos($path, '?')+1);
    if ($paramstring == ''){
      echo '  RewriteRule ^' . str_replace('.', '\.' . $filename) . '$ ' . $url_new[$key] . ' [R=301,L]' . '<br/>';
    } else {
      echo '  RewriteCond %{QUERY_STRING} (^)' . $paramstring . '($)<br/>';
      echo '  RewriteRule ^' . str_replace('.', '\.', $filename) . ' ' . $url_new[$key] . '? [R=301,L]<br/><br/>';
    }
  }
}

Il codice si spiega praticamente da solo:

  1. per prima cosa si toglie il dominio dagli indirizzi (in questo caso nelle regole htaccess non ci serve)
  2. poi si divide in due parti quello che rimane: il percorso di base e gli eventuali parametri
  3. nel caso non ci siano parametri si crea la regola semplice
  4. nel caso invece siano presenti uno o più parametri, si aggiunge la condizione RewriteCond.

Molto bello! Ho capito alcune cose fondamentali e ho risolto il problema di fare redirect alle pagine meglio indicizzate di un sito.

Ma se io metto questo script al posto della index.php del vecchio sito, ci vorrà comunque una regola .htaccess che mandi il navigante su questo script.

Esempio: io cerco di accedere a
http://www.example.com/directory/page.asp?arg1=param1
se lo script è sulla / root del sito, non verrà intercettato.
quindi ci vuole prima un .htaccess che intercetti tutte le chiamate a tutte le sottocartelle e le dirige verso il mio script. Questo poi valuta che pagina ho chiesto e mi redirige di nuovo...

So che si può fare una regola come questa, molti MVC la installano, ma non riesco ancora a destreggiarmi con le configurazioni apache...

Mi sbaglio?
ciao
Domenico

Caro Domenico, lo script PHP presentato è solo un modo per generare delle regole per il file .htaccess in maniera veloce, l'ho fatto in PHP ma potevo scriverlo anche in un altro linguaggio. Il risultato dello script andrà copiato ed incollato nel file .htaccess :-)

grazie, comunque mi è stato utile per scrivere il .htaccess corretto (sembra) dovendo muovermi da miosito.com/vecchiocms a miosito.com/nuovocms con schema di url molto diverso avrei voluto mettere i redirect delle pagine più importanti e poi chiudere il tutto con un: "case else: miosito.nuovocms/index.php ma pazienza....

ciao

Cavolo grazie, questo mi serviva !!!

Domenico se la fai direttamente sulla root non importa delle sottocartele, funzionerà sull'intero sito!

Ma se in un file .htaccess devo solo fare dei redirect 301, cosa devo scrivere prima?
Sarò più chiaro con un esempio:

Supponiamo che debba fare un redirect di questo tipo:

redirect 301 /old http://www.miosito.it/new

Esattamente cosa devo scrivere prima e dopo questa istruzione nel file .htaccess?

Ci va il rewriteengine on? il rewrite base?

È incredibile come non riesco a trovare documentazione su una cosa così. Grazie per la vostra risposta.

@Melchiorre: prima delle regole per i redirect dovrai attivare la riscrittura degli URL aggiungendo la seguente riga:

  RewriteEngine on

Ciao FiNeX, credo il tuo script faccia proprio al caso mio, solo una cosa: praticamente preparo una pagina php che una volta lanciata mi darà la regola fatta e finita da copiare sul file .htaccess, giusto? grazie