Press "Enter" to skip to content

PHP Permalink: perchè e come crearli

Condividi il post con i tuoi amici o colleghi

Con l’articolo SEO: come impostare correttamente le url del proprio sito/blog? abbiamo visto come si devono impostare le url di un sito web per ottenere dei benefici lato SEO.

Oggi vediamo come realizzare un permalink utilizzando il linguaggio PHP. Un permalink è un link permanente che punta ad una pagina web (o anche a un post di un blog). Il permalink non cambia nel tempo, questo permette di identificare univocamente una risorsa sul web e, nel caso di link in entrata o citazioni, non si perderà traffico modificando il contenuto…salvo aver commesso errori di SEO Copywriting. Ma questo è un altro discorso 😉

Nelle nostre web applications realizzeremo i permalink a partire da stringhe di testo. Nel caso degli articoli di un blog è opportuno trasformare in permalink il titolo stesso degli articoli. Il tutto semplicemente grazie all’utilizzo di una funzione come la seguente:

function permalink($string) {
$string = strtolower($string);
$string = preg_replace("/[^0-9A-Za-z ]/", "", $string);
$string = str_replace(" ", "-", $string);
while (strstr($string, "--")) {
$string = preg_replace("/--/", "-", $string);
		}
return($string);
}

Passiamo come parametro il titolo del post (o comunque un testo ottimizzato SEO) ed otterremo il testo correttamente formattato, pronto per essere utilizzato in un permalink. Gli spazi saranno sostituiti dal carattere – (meno), carattere consigliato per separare le parole in una url. Caratteri accentati ed apici vari verranno rimossi, ricordiamoci che un permalink è l’indirizzo di una pagina web e non tutti i caratteri sono consentiti.

Ecco perchè è utile utilizzare una funzione ad hoc 😉

p.s ora tocca a te: la funzione non è perfetta…se trovi il problema segnalalo nei commenti 😀


Condividi il post con i tuoi amici o colleghi

  1. protected function slugify($text)
    {
    // replace non letter or digits by -
    $text = preg_replace('~[^\\pL\d]+~u', '-', $text);

    // trim
    $text = trim($text, '-');

    // transliterate
    if (function_exists('iconv'))
    {
    $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
    }

    // lowercase
    $text = strtolower($text);

    // remove unwanted characters
    $text = preg_replace('~[^-\w]+~', '', $text);

    if (empty($text))
    {
    return 'n-a';
    }

    return $text;
    }

    Variante proposta da Fabien Potencier in una delle sue tante guide su symfony.
    Da notare la trasliteration, un ottimo sistema per sostituire i caratteri accentati con la controparte non accentata

  2. l’indentazione è andata a quel paese purtroppo :S

        protected function slugify($text)
        {
            // replace non letter or digits by -
            $text = preg_replace('~[^\\pL\d]+~u', '-', $text);
    
            // trim
            $text = trim($text, '-');
    
            // transliterate
            if (function_exists('iconv'))
            {
                $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
            }
    
            // lowercase
            $text = strtolower($text);
    
            // remove unwanted characters
            $text = preg_replace('~[^-\w]+~', '', $text);
    
            if (empty($text))
            {
                return 'n-a';
            }
    
            return $text;
        }
    
  3. @Loige il problema della funzione era proprio quello,

    non converte i caratteri accentati nelle controparti non accentate 😉

  4. Io ho tagliato la testa al toro offrendomi la possibilità di personalizzare nel minimi dettagli gli url, per avere una SEO più raffinata possibile.

    Nel cms, per ogni contenuto ho un campo “url” nella quale inserirò l’indirizzo che la pagina avrà. Il cms si occupa di creare un file dal nome che io ho definito, dentro il quale piazza una require con un template specifico.

    Il template inizia il suo lavoro chiedendosi quale pagina lo richiama ($_SERVER[‘PHP_SELF’]), quindi fa una query usando come where il nome pagina, richiamando i contenuti collegati.

    L’unica cosa negativa è che crea parecchi file, ma non è un problema dato che pesano pochi byte 🙂

  5. Ciao Joel, benvenuto su EWD 🙂

    Se ho capito bene, mi hai descritto un sistema di caching per le pagine. Altra cosa molto utile in un cms. Come operi anche tu, è opportuno salvare in un campo del record “permalink” il titolo del post (o della pagina web) formattato dalla funzione creata ad hoc.

    A completamento del tutto, un bel file htaccess per attuare l’ url rewrite 😉

  6. Io credo invece che joel abbia creato una sorta di cms totalmente file-based

  7. @Loige

    Io utilizzo una mia funzione dove ho creato una corrisposndenza tra entità html tipo la e accentata e il suo relativo non accentato.
    La funzione che hai proposto è molto molto utile e potente! La proverò

    ciao

  8. Ringraziate Fabien Potencier 😛 io l’ho scoperta per caso mentre leggevo alcune guide sul suo framework php symphony 🙂

    @Luca
    Ad ogni modo (e qua chiamo in causa Emanuele che di certo ne saprà più di me) non credo ti convenga inserire le entities negli url… suppongo che non tutti i crawler riuscirebbero ad indicizzarle correttamente…
    Anche perchè wordpress, drupal, symphony e co. avrebbero potuto usare le entities e sarebbe stato di certo più semplice e performante… Per adottare la tecnica della tanslitterazione (rimuovere gli accenti) avranno avuto dei buoni motivi suppongo…

    Ma ripeto, in ogni caso dovremmo documentarci meglio al riguardo 😉

  9. sicuramente le entità html sono da evitare io utilizzo una funzione che fa questo:

    str_replace(
    		array(
    			"!",","," ","=","'","*","#",
    			"ª","à","è","é","ì","ò","ù","ç",
    			"ñ",'"','&',"@",':','?','(',')','[',']','{','*',
    			'}','.',';','°','/','\\'),
    		array(
    			"","","-","-","","","",
    			"a","a","e","e","i","o","u","c",
    			"n","",'e',"",'','','','','','','','',
    			'','','','','-','-'),
    		htmlentities(strtolower($parametro))
    		);
    

    oltre a fare altre verifiche.

  10. Ciao EmaWebDesign 🙂

    no nessun sistema di caching o di url rewrite. Mi spiego meglio:

    Io non ho una doppia url per ogni post (url originale con variabili appiccicate e url like SEO, aka permalink). Ne ho solo una, che ho stabilito al momento della creazione del contenuto direttamente nel mio CMS.

    Una volta che salvo il contenuto, il CMS crea un file con dentro un unica include di un template generico. Il template si occupa di fare una query al DB usando l’url della pagina come criterio di selezione.

    Una roba simile insomma:

    $pagina = $_SERVER[‘PHP_SELF’];

    $query_select = mysql_query(“SELECT * FROM contenuti WHERE nomeweb=’$pagina’”) or die(“Errore query database: ” . mysql_error());

    Preferisco evitare sistemi automatici di creazione link, spesso si può fare meglio “a mano” 🙂

  11. @luca
    Così và sicuramente meglio di come avevo pensato… in ogni caso se hai installata l’estensione iconv ti consiglio di usarla ed eseguire la translitterazione… sarà probabilmente più affidabile, ma in ogni caso più performante (poichè si tratta di una funzione nativa scritta direttamente in c, e in genere le funzioni native sono almeno 10 volte più veloci di quelle self-made in php)…

    Qualcosa del genere potrebbe fare al caso tuo, fornendo anche la degradation nel caso in cui iconv non fosse disponibile…

     if (function_exists('iconv'))
            {
                $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
            }
    else
    // chiama la tua funzione di traslitterazione
    

    @Joel
    Avevo inteso bene allora 🙂
    Sicuramente ci avrai già pensato, ma stai attento alle sql injection, perchè da come hai presentato il tuo esempio è facilissimo inserire un url “artefatto” in modo tale da eseguire una qualsiasi quary sul tuo db…
    In caso tu non ci abbia già pensato, la funzione mysql_real_escape() già potrebbe essere un buon tampone… quindi dovresti fare qualcosa del genere:

    $pagina = mysql_real_escape($_SERVER['PHP_SELF']);
    $query_select = mysql_query(“SELECT * FROM contenuti WHERE nomeweb=’$pagina’”) or die(“Errore query database: ” . mysql_error());
    


    spero di esservi stato utile (e di non aver detto fesserie XD)
    a presto

  12. @Luca è indubbio che i caratteri accentati devono essere convertiti nella controparte non accentata.

    Anche un str_replace è utile per raggiungere l’obiettivo 😉

Comments are closed.