PHP - Post-Redirect-Get (PRG)

Ciao there, aspiranti programmatori! Oggi esploreremo un importante schema di sviluppo web chiamato Post-Redirect-Get, o PRG per brevissimo. Non preoccupatevi se siete nuovi alla programmazione; vi guiderò attraverso questo concetto passo dopo passo, proprio come ho fatto per innumerevoli studenti nei miei anni di insegnamento. Allora, prendete una tazza di caffè (o la vostra bevanda preferita) e intraprendiamo insieme questo viaggio entusiasmante!

PHP - Post-Redirect-Get (PRG)

Cos'è il Post-Redirect-Get (PRG)?

Immaginate di compilare un modulo per ordinare una pizza online. Cliccate su invia, e poi... oops! Avete accidentalmente ricaricato la pagina. Improvvisamente, avete ordinato due pizze invece di una! Questo è il tipo di problema che lo schema PRG aiuta a risolvere.

PRG è uno schema di progettazione per lo sviluppo web che previene le sottomissioni duplicate del modulo quando un utente ricarica la pagina dopo aver inviato un modulo. È come un vigile urbano per le vostre applicazioni web, assicurando che i dati scorrono senza intoppi e non vengono accidentalmente duplicati.

Come Funziona il PRG

  1. L'utente invia un modulo utilizzando una richiesta POST.
  2. Il server elabora i dati del modulo.
  3. Invece di inviare una risposta direttamente, il server invia un reindirizzamento (solitamente a una pagina di successo).
  4. Il browser dell'utente segue il reindirizzamento con una richiesta GET.
  5. Il server risponde alla richiesta GET con la pagina finale.

Ora, vediamo questo in azione con alcuni esempi di codice!

Esempio 1: Una Semplice Implementazione PRG

Iniziamo con un esempio di base di come funziona il PRG in PHP. Creeremo un semplice modulo che permette agli utenti di inviare il loro colore preferito.

Passo 1: Il Modulo HTML (form.php)

<!DOCTYPE html>
<html>
<head>
<title>Modulo Colore Preferito</title>
</head>
<body>
<h1>Qual è il Tuo Colore Preferito?</h1>
<form action="process.php" method="post">
<input type="text" name="color" required>
<input type="submit" value="Invia">
</form>
</body>
</html>

Questo modulo invia una richiesta POST a process.php quando viene inviato.

Passo 2: Elaborazione del Modulo (process.php)

<?php
session_start();

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$color = $_POST['color'];

// Salva il colore nella sessione
$_SESSION['favorite_color'] = $color;

// Reindirizza alla pagina dei risultati
header('Location: result.php');
exit;
} else {
// Se qualcuno tenta di accedere a questa pagina direttamente, reindirizzalo al modulo
header('Location: form.php');
exit;
}

Spieghiamo un po':

  1. Iniziamo una sessione per conservare i dati tra le pagine.
  2. Controlliamo se il metodo di richiesta è POST.
  3. Se lo è, salviamo il colore inviato nella sessione.
  4. Poi reindirizziamo l'utente a result.php.
  5. Se qualcuno tenta di accedere a questa pagina direttamente (non tramite POST), lo reindirizziamo al modulo.

Passo 3: Visualizzazione del Risultato (result.php)

<?php
session_start();

if (isset($_SESSION['favorite_color'])) {
$color = $_SESSION['favorite_color'];
// Pulisci la variabile di sessione per evitare la visualizzazione di dati vecchi al ricaricare
unset($_SESSION['favorite_color']);
} else {
$color = 'Nessun colore inviato';
}
?>

<!DOCTYPE html>
<html>
<head>
<title>Tuo Colore Preferito</title>
</head>
<body>
<h1>Tuo Colore Preferito</h1>
<p>Hai detto che il tuo colore preferito è: <?php echo htmlspecialchars($color); ?></p>
<a href="form.php">Invia un altro colore</a>
</body>
</html>

Ecco cosa sta succedendo:

  1. Iniziamo la sessione di nuovo per accedere ai dati conservati.
  2. Controlliamo se un colore preferito è stato conservato nella sessione.
  3. Se lo è, lo visualizziamo e poi puliamo la variabile di sessione.
  4. Se non lo è, visualizziamo un messaggio predefinito.

Ora, anche se l'utente ricarica la pagina dei risultati, non risottometterà i dati del modulo. Non è fantastico?

Esempio 2: PRG con Interazione Database

Portiamo il nostro esempio un passo avanti e immaginiamo di gestire un sistema di ordinazione di pizze. Utilizzeremo un database per conservare gli ordini e implementeremo PRG per prevenire ordini duplicati.

Passo 1: Il Modulo di Ordine (order_form.php)

<!DOCTYPE html>
<html>
<head>
<title>Modulo Ordine Pizza</title>
</head>
<body>
<h1>Ordina la Tua Pizza</h1>
<form action="process_order.php" method="post">
<label for="pizza_type">Tipo di Pizza:</label>
<select name="pizza_type" id="pizza_type" required>
<option value="margherita">Margherita</option>
<option value="pepperoni">Pepperoni</option>
<option value="veggie">Veggie</option>
</select>
<br><br>
<label for="size">Dimensione:</label>
<select name="size" id="size" required>
<option value="small">Piccola</option>
<option value="medium">Media</option>
<option value="large">Grande</option>
</select>
<br><br>
<input type="submit" value="Effettua Ordine">
</form>
</body>
</html>

Passo 2: Elaborazione dell'Ordine (process_order.php)

<?php
session_start();

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$pizza_type = $_POST['pizza_type'];
$size = $_POST['size'];

// In una applicazione reale, vorresti sanificare e validare questo input

// Connettiti al database (solitamente metteresti questo in un file separato)
$db = new PDO('mysql:host=localhost;dbname=pizza_shop', 'username', 'password');

// Inserisci l'ordine
$stmt = $db->prepare("INSERT INTO orders (pizza_type, size) VALUES (?, ?)");
$stmt->execute([$pizza_type, $size]);

// Ottieni l'ID dell'ordine
$order_id = $db->lastInsertId();

// Salva l'ID dell'ordine nella sessione
$_SESSION['last_order_id'] = $order_id;

// Reindirizza alla pagina di conferma
header('Location: order_confirmation.php');
exit;
} else {
// Se qualcuno tenta di accedere a questa pagina direttamente, reindirizzalo al modulo
header('Location: order_form.php');
exit;
}

Questo script:

  1. Elabora i dati del modulo.
  2. Inserisce l'ordine nel database.
  3. Salva l'ID dell'ordine nella sessione.
  4. Reindirizza a una pagina di conferma.

Passo 3: Conferma dell'Ordine (order_confirmation.php)

<?php
session_start();

if (isset($_SESSION['last_order_id'])) {
$order_id = $_SESSION['last_order_id'];
// Pulisci la variabile di sessione
unset($_SESSION['last_order_id']);

// In una applicazione reale, recupereresti i dettagli dell'ordine dal database qui
// Per questo esempio, visualizzeremo solo l'ID dell'ordine
$message = "Il tuo ordine (ID: $order_id) è stato effettuato con successo!";
} else {
$message = "Nessun ordine recente trovato. Effettua un nuovo ordine.";
}
?>

<!DOCTYPE html>
<html>
<head>
<title>Conferma Ordine</title>
</head>
<body>
<h1>Conferma Ordine</h1>
<p><?php echo htmlspecialchars($message); ?></p>
<a href="order_form.php">Effettua un altro ordine</a>
</body>
</html>

Questa pagina di conferma:

  1. Recupera l'ID dell'ordine dalla sessione.
  2. Visualizza un messaggio di conferma.
  3. Pulisce la variabile di sessione per evitare la visualizzazione dello stesso ordine al ricaricare.

Perché il PRG è Importante

  1. Previene le Sottomissioni Duplicate: Se un utente ricarica la pagina di conferma, non risottometterà accidentalmente il proprio ordine.
  2. Migliora l'Esperienza Utente: Gli utenti vedono un URL pulito nella loro barra degli indirizzi, non una lunga stringa di dati del modulo.
  3. Segue i Principi REST: Le richieste GET vengono utilizzate per recuperare dati, mentre le richieste POST vengono utilizzate per sottomettere dati.

Metodi Comuni PRG

Ecco una tabella dei metodi comuni utilizzati nello schema PRG:

Metodo Descrizione
$_SERVER['REQUEST_METHOD'] Controlla il metodo di richiesta HTTP (GET, POST, ecc.)
header('Location: ...') Invia un header di reindirizzamento al browser
exit Assicura che nessun altro codice venga eseguito dopo il reindirizzamento
session_start() Inizia una nuova sessione o riprende una sessione esistente
$_SESSION Salva e recupera dati nella sessione
isset() Controlla se una variabile è impostata e non è NULL
unset() Distrugge una variabile specificata

Ricorda, giovani padawans, lo schema PRG è come utilizzare la Forza nello sviluppo web. Porta equilibrio alle tue applicazioni, prevenendo il lato oscuro delle sottomissioni duplicate del modulo. May the code be with you!

In conclusione, lo schema Post-Redirect-Get è uno strumento potente nel tuo toolkit di sviluppo web. Aiuta a creare applicazioni più robuste e user-friendly prevenendo sottomissioni accidentali duplicate. Mentre continui il tuo viaggio in PHP e nello sviluppo web, troverai molte situazioni in cui PRG può salvare la giornata. Continua a praticare, rimani curioso e happy coding!

Credits: Image by storyset