Migliorare la SEO di un sito PHP e MariaDB con Slug e sintassi REST
Categoria: SEO & Sviluppo Web | Livello: Intermedio
Quando si costruisce un sito web dinamico con PHP e MariaDB, uno degli aspetti più trascurati — ma cruciali per il posizionamento su Google — è la struttura degli URL. Un sito con URL del tipo articolo.php?id=123 è penalizzato rispetto a uno che usa articolo/come-migliorare-la-seo.
In questo articolo vedremo come trasformare un sito PHP/MariaDB in una macchina SEO-friendly usando slug e principi REST.
Perché gli URL parlanti sono importanti per la SEO
Google e gli altri motori di ricerca leggono l'URL per capire il contenuto della pagina. Un URL descrittivo:
- Migliora il ranking: Google premia URL chiari e leggibili
- Aumenta il CTR: gli utenti cliccano più volentieri su URL che capiscono
- Favorisce la condivisione: un URL pulito è più facile da copiare e condividere
- Aiuta i crawler: una struttura gerarchica permette ai bot di indicizzare meglio il sito
| ❌ URL brutto | ✅ URL SEO-friendly |
|---|---|
blog.php?id=45 |
blog/guida-alla-seo |
categoria.php?cat=3&page=2 |
categoria/programmazione/pagina/2 |
prodotto.php?id=12&ref=footer |
prodotto/php-mysql-corso |
Cos'è uno slug?
Uno slug è la parte leggibile di un URL che identifica una risorsa in modo univoco. Deriva dal titolo della pagina, trasformato in una stringa URL-safe:
"I migliori trucchi SEO per PHP" → "migliori-trucchi-seo-php"
Funzione PHP per generare slug
<?php
function generaSlug(string $testo): string
{
$slug = mb_strtolower($testo, 'UTF-8');
$slug = str_replace(['è', 'é', 'ê', 'ë'], 'e', $slug);
$slug = str_replace(['à', 'á', 'â', 'ã', 'ä'], 'a', $slug);
$slug = str_replace(['ì', 'í', 'î', 'ï'], 'i', $slug);
$slug = str_replace(['ò', 'ó', 'ô', 'õ', 'ö'], 'o', $slug);
$slug = str_replace(['ù', 'ú', 'û', 'ü'], 'u', $slug);
$slug = preg_replace('/[^a-z0-9]+/', '-', $slug);
$slug = trim($slug, '-');
return $slug;
}
?>
Architettura RESTful con PHP
Un'architettura REST si basa su risorse identificate da URL gerarchici. Per applicarla a un sito PHP tradizionale:
1. Struttura delle tabelle in MariaDB
Aggiungi una colonna slug alle tue tabelle principali:
CREATE TABLE articoli (
id INT AUTO_INCREMENT PRIMARY KEY,
titolo VARCHAR(255) NOT NULL,
slug VARCHAR(255) NOT NULL UNIQUE,
contenuto TEXT,
data_pub DATE,
categoria_id INT,
INDEX idx_slug (slug)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Il vincolo UNIQUE sullo slug garantisce che non ci siano duplicati, e l'INDEX velocizza le lookup.
2. Salvare lo slug all'inserimento
<?php
$titolo = $_POST['titolo'] ?? '';
$slug = generaSlug($titolo);
// Verifica unicità
$stmt = $pdo->prepare("SELECT COUNT(*) FROM articoli WHERE slug = ?");
$stmt->execute([$slug]);
$count = $stmt->fetchColumn();
if ($count > 0) {
$slug .= '-' . uniqid();
}
$stmt = $pdo->prepare("
INSERT INTO articoli (titolo, slug, contenuto, data_pub, categoria_id)
VALUES (?, ?, ?, ?, ?)
");
$stmt->execute([$titolo, $slug, $contenuto, $data, $categoriaId]);
?>
3. Routing con .htaccess (Apache)
Il cuore della sintassi REST è il rewriting degli URL. Con Apache, usa il file .htaccess nella root:
RewriteEngine On
# Reindirizza gli URL con query string a slug (solo per旧 URL legacy)
RewriteCond %{QUERY_STRING} ^id=(\d+)$
RewriteRule ^articolo\.php$ articolo/%1? [R=301,L]
# Routing delle risorse
RewriteRule ^articolo/([a-z0-9-]+)$ articolo.php?slug=$1 [L,QSA]
RewriteRule ^categoria/([a-z0-9-]+)$ categoria.php?slug=$1 [L,QSA]
RewriteRule ^categoria/([a-z0-9-]+)/pagina/(\d+)$ categoria.php?slug=$1&pagina=$2 [L,QSA]
Con Nginx:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ ^/articolo/([a-z0-9-]+)$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/articolo.php;
fastcgi_param QUERY_STRING slug=$1;
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
}
4. Recuperare l'articolo tramite slug
<?php
// articolo.php
$slug = $_GET['slug'] ?? '';
if (!$slug) {
header('HTTP/1.0 404 Not Found');
exit('Articolo non trovato');
}
$stmt = $pdo->prepare("SELECT * FROM articoli WHERE slug = ? LIMIT 1");
$stmt->execute([$slug]);
$articolo = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$articolo) {
header('HTTP/1.0 404 Not Found');
exit('Articolo non trovato');
}
?>
URL canonici e redirect 301
Quando migri da URL con ID a slug, Google potrebbe aver già indicizzato i vecchi URL. È fondamentale:
<?php
// Se arriva una richiesta con ?id=N, reindirizza 301 allo slug
if (isset($_GET['id'])) {
$stmt = $pdo->prepare("SELECT slug FROM articoli WHERE id = ?");
$stmt->execute([$_GET['id']]);
$slug = $stmt->fetchColumn();
if ($slug) {
header("HTTP/1.1 301 Moved Permanently");
header("Location: /articolo/$slug");
exit;
}
}
?>
Aggiungi anche il tag canonical nell'head HTML:
<link rel="canonical" href="https://www.example.com/articolo/<?= htmlspecialchars($articolo['slug']) ?>">
Best practice SEO aggiuntive
Meta tag dinamici
<?php
function mostraMeta(array $articolo): void
{
$descrizione = mb_substr(strip_tags($articolo['contenuto']), 0, 155);
?>
<title><?= htmlspecialchars($articolo['titolo']) ?> | Mio Sito</title>
<meta name="description" content="<?= htmlspecialchars($descrizione) ?>">
<meta property="og:title" content="<?= htmlspecialchars($articolo['titolo']) ?>">
<meta property="og:description" content="<?= htmlspecialchars($descrizione) ?>">
<meta property="og:url" content="https://www.example.com/articolo/<?= $articolo['slug'] ?>">
<link rel="canonical" href="https://www.example.com/articolo/<?= $articolo['slug'] ?>">
<?php
}
?>
Sitemap XML dinamica
<?php
// sitemap.php
header('Content-Type: application/xml; charset=utf-8');
$stmt = $pdo->query("SELECT slug, data_pub FROM articoli ORDER BY data_pub DESC");
?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<?php while ($row = $stmt->fetch(PDO::FETCH_ASSOC)): ?>
<url>
<loc>https://www.example.com/articolo/<?= $row['slug'] ?></loc>
<lastmod><?= $row['data_pub'] ?></lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<?php endwhile; ?>
</urlset>
Poi aggiungi al .htaccess:
RewriteRule ^sitemap\.xml$ sitemap.php [L]
Schema.org JSON-LD per i dati strutturati
I dati strutturati aiutano Google a generare i rich snippet nei risultati di ricerca:
<?php
function stampaJsonLd(array $articolo): void
{
$json = [
'@context' => 'https://schema.org',
'@type' => 'Article',
'headline' => $articolo['titolo'],
'description' => mb_substr(strip_tags($articolo['contenuto']), 0, 155),
'datePublished' => $articolo['data_pub'],
'url' => "https://www.example.com/articolo/{$articolo['slug']}",
];
?>
<script type="application/ld+json">
<?= json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) ?>
</script>
<?php
}
?>
Riepilogo
| Componente | Cosa fa per la SEO |
|---|---|
| Slug | URL leggibili e keyword-rich |
| Routing REST | Struttura gerarchica e pulita |
| Redirect 301 | Preserva il posizionamento dei vecchi URL |
| Tag canonical | Evita contenuti duplicati |
| Meta tag dinamici | Ottimizza snippet nei risultati |
| Sitemap XML | Aiuta i crawler a scoprire tutte le pagine |
| JSON-LD | Abilita i rich snippet |
Conclusioni
Migliorare la SEO di un sito PHP/MariaDB non richiede framework complessi. Con poche modifiche mirate — slug, routing REST, reindirizzamenti 301 e meta tag dinamici — puoi ottenere un salto significativo nel posizionamento su Google.
La chiave è la coerenza: una volta adottata la struttura REST, tutti gli URL del sito devono seguirla. I vecchi URL devono essere reindirizzati permanentemente (301), e ogni nuova pagina deve nascere con il suo slug.
Articolo pubblicato su filippobilardo.it — Tutti i diritti riservati