4E e 4I SIA: la pagina action.php spiegata riga per riga

 Oggi analizziamo questo file, `action.php`. Come suggerisce il nome, questo file non è fatto per essere "visto", ma per "agire". È il "motore" che sta dietro i nostri bottoni "Salva", "Modifica" ed "Elimina". Riceve comandi e dati, li elabora, e poi ci rimanda a una pagina di visualizzazione.

Analizziamolo riga per riga.


Preparazione e Impostazioni Iniziali

<?php

// action.php

include("setting.php");

  * **Riga 1 (`<?php`):** Semplice, apre il blocco di codice PHP.

  * **Riga 2 (`// action.php`):** Un commento. È una buona abitudine scrivere il nome del file all'inizio, così sappiamo sempre dove siamo.

  * **Riga 3 (`include("setting.php");`):** Questa è una riga molto importante. Stiamo "importando" un altro file. Possiamo immaginare che dentro `setting.php` ci sia la variabile `$my_database_txt`, che contiene il nome del nostro file di testo (es. `database.txt`). Includerlo qui ci permette di usare quella variabile in questo script.

<!-- end list -->

// Definiamo il carattere separatore

$sep = "|"; 

// Definiamo i caratteri da rimuovere per sicurezza

$bad_char = array("|", "\r\n", "\r", "\n");

  * **Riga 6 (`$sep = "|";`):** Definiamo una variabile per il nostro separatore. Dato che stiamo usando un file di testo come database, dobbiamo decidere come separare un campo (es. "Nome") da un altro (es. "Prodotto"). Qui scegliamo di usare il carattere "pipe" (`|`).

  * **Riga 8 (`$bad_char = ...;`):** Creiamo un "array" (un contenitore) di caratteri che consideriamo "pericolosi" o "problematici".

      * `"|"`: Non vogliamo che l'utente inserisca un `|` nel nome, altrimenti sballerebbe la nostra suddivisione in colonne.

      * `"\r\n", "\r", "\n"`: Questi sono i caratteri "a capo". Se un utente li inserisse, creerebbe una nuova riga nel mezzo di un dato, corrompendo il nostro file.

### 2\. Blocco 1: SCRITTURA (Inserimento di nuovi dati)

Questo è il primo grande blocco logico. Si attiva solo se riceve un comando specifico.

/*************************

 SCRITTURA (INSERIMENTO)

**************************/

if (isset($_POST['scrivi'])) {

  * **Riga 13 (`if (isset($_POST['scrivi'])) {`):** Questa è la porta d'ingresso per la scrittura. Il codice controlla: "Mi sono arrivati dati tramite il metodo `POST` (tipico dei form HTML) E, tra questi dati, c'è un elemento chiamato `scrivi`?"

      * `$_POST` è un array speciale che contiene tutti i dati inviati da un form.

      * `isset()` è una funzione che controlla se una variabile esiste.

      * Quindi, questo blocco si attiva solo se abbiamo premuto un bottone "salva" o "invia" che nel form HTML aveva l'attributo `name="scrivi"`.

<!-- end list -->

    if (!is_writable($my_database_txt)) {

        // Creiamo il file se non esiste e diamo i permessi

        if (!file_exists($my_database_txt)) {

            touch($my_database_txt);

            chmod($my_database_txt, 0666);

        } else {

             exit("Errore: il file non ha i permessi di scrittura!...");

        }

    }

  * **Riga 14 (`if (!is_writable(...))`):** È un controllo di sicurezza. `is_writable` verifica se abbiamo i permessi per scrivere sul file database. Il `!` all'inizio significa "NOT" (non). Quindi: "Se il file NON è scrivibile...".

  * **Riga 16 (`if (!file_exists(...))`):** Se non è scrivibile, controlliamo *perché*. "Forse perché il file NON esiste?".

  * **Riga 17 (`touch(...);`):** Se non esiste, questa funzione lo crea vuoto.

  * **Riga 18 (`chmod(...);`):** Diamo al file appena creato i permessi di lettura e scrittura per tutti (è quello che significa `0666`).

  * **Riga 19-21 (`else { exit(...); }`):** Se invece il file *esiste* ma *non* è scrivibile, c'è un problema di permessi sul server. È inutile continuare, quindi lo script si ferma (`exit`) e mostra un messaggio di errore chiaro.

<!-- end list -->

    // 1. Riceviamo i 5 campi dal form di inserimento

    $nome_cliente = str_replace($bad_char, "", $_POST['nome_cliente']);

    $prodotto = str_replace($bad_char, "", $_POST['prodotto']);

    $quantita = str_replace($bad_char, "", $_POST['quantita']);

    $prezzo_unitario = str_replace($bad_char, "", $_POST['prezzo_unitario']);

    $note = str_replace($bad_char, "", $_POST['note']);

  * **Righe 25-29:** Qui "puliamo" i dati ricevuti dal form. Per ogni campo (es. `$_POST['nome_cliente']`):

      * Usiamo la funzione `str_replace()` per prendere l'array `$bad_char` (i caratteri cattivi) e sostituirli con `""` (una stringa vuota), di fatto **eliminandoli**.

      * Il risultato pulito viene salvato in una nuova variabile (es. `$nome_cliente`). Questo passaggio è fondamentale per la sicurezza e l'integrità dei dati.

<!-- end list -->

    // 2. Validiamo e calcoliamo il totale (importante!)

    $quantita_num = (float)$quantita; // Convertiamo in numero

    $prezzo_unitario_num = (float)$prezzo_unitario; // Convertiamo in numero

    $totale = $quantita_num * $prezzo_unitario_num; // Calcolo

  * **Riga 32-33:** I dati che arrivano da un form sono **sempre testo** (stringhe). Per fare calcoli matematici, dobbiamo convertirli in numeri.

      * `(float)` è un "cast": forza la variabile a destra (es. `$quantita`) a diventare un numero con la virgola (un *float*).

  * **Riga 34:** Ora che sono numeri, possiamo calcolare il totale moltiplicandoli.

<!-- end list -->

    // 3. Apriamo il file in modalità "append" (a+)

    $open = fopen($my_database_txt, "a+");

  * **Riga 37:** Apriamo il nostro file database. `fopen` è la funzione per farlo.

      * La modalità `"a+"` è cruciale: `"a"` sta per "append", cioè "aggiungi in fondo". Questo fa sì che non cancelliamo i dati vecchi, ma scriviamo il nuovo dato *dopo* tutti gli altri. Il `+` aggiunge la possibilità di leggere (anche se qui non la usiamo).

<!-- end list -->

    // 4. Creiamo la stringa da scrivere (tutti e 6 i campi)

    $riga = $nome_cliente . $sep .

            $prodotto . $sep .

            $quantita_num . $sep .

            $prezzo_unitario_num . $sep .

            $note . $sep .

            $totale . "\r\n"; // Aggiungiamo il totale alla fine

  * **Righe 40-45:** Prepariamo la riga di testo da salvare.

      * Il `.` (punto) in PHP è l'operatore di "concatenazione": unisce le stringhe.

      * Stiamo unendo i 5 campi puliti E il `$totale` calcolato, separandoli con la nostra variabile `$sep` (che conteneva `|`).

      * **Riga 45:** Alla fine aggiungiamo `"\r\n"`, che è il codice universale per "andare a capo". Questo assicura che il prossimo record verrà scritto su una nuova riga.

<!-- end list -->

    // 5. Scriviamo sul file

    fwrite($open, $riga);

    fclose($open);

  * **Riga 48 (`fwrite(...);`):** Questa è l'azione di scrittura\! Scrive la nostra stringa `$riga` nel file che abbiamo aperto (`$open`).

  * **Riga 49 (`fclose(...);`):** Chiudiamo il file. È un'operazione importantissima, come "salvare" e chiudere un documento Word. Libera la risorsa.

<!-- end list -->

    // 6. Ritorniamo alla pagina di visualizzazione

    header("location: lettura.php");

    exit;

}

  * **Riga 52 (`header(...);`):** Questa riga dice al browser: "Ok, ho finito il mio lavoro. Adesso, per favore, vai alla pagina `lettura.php`". Questo si chiama "redirect". È per questo che l'utente, dopo aver salvato, si ritrova sulla pagina che mostra l'elenco aggiornato.

  * **Riga 53 (`exit;`):** Ferma immediatamente l'esecuzione di questo script. È buona pratica farlo dopo un redirect.

3\. Blocco 2: ELIMINARE UNA RIGA

Se non abbiamo premuto "scrivi", lo script controlla la prossima condizione.

/*************************

 ELIMINARE UNA RIGA

**************************/

else if (isset($_GET['delete'])) {

  * **Riga 58 (`else if (isset($_GET['delete'])) {`):** "Altrimenti, se non stavo scrivendo, controllo: mi è arrivato un comando tramite `GET` (cioè nell'URL) chiamato `delete`?".

      * `$_GET` è l'array che contiene i dati passati nell'URL. Un link di eliminazione sarà simile a `action.php?delete=2`.

      * Questo blocco si attiva se l'URL contiene `?delete=...`.

<!-- end list -->

    // Questo blocco è identico al tuo e funziona bene

    $riga_da_cancellare = $_GET['delete'];

  * **Riga 61:** Recuperiamo il valore associato a "delete". Se l'URL era `...delete=2`, `$riga_da_cancellare` ora conterrà `2`. Questo `2` è l'**indice** (il numero) della riga che vogliamo rimuovere.

<!-- end list -->

    $array_righi = file($my_database_txt); // Leggiamo il file in un array

    unset($array_righi[$riga_da_cancellare]); // Rimuoviamo la riga specificata

  * **Riga 63 (`file(...);`):** Questa è una scorciatoia potentissima. La funzione `file()` legge l'intero file `database.txt` e lo carica in un array, dove **ogni riga del file diventa un elemento dell'array**.

  * **Riga 64 (`unset(...);`):** Questa è la funzione che "distrugge" una variabile o un elemento di un array. Stiamo dicendo: "Prendi l'array di righe, vai all'indice `$riga_da_cancellare` (es. 2) e distruggi quell'elemento". L'array ora ha un "buco".

<!-- end list -->

    // Riscriviamo il file senza la riga cancellata

    $open = fopen($my_database_txt, "w");

    foreach ($array_righi as $key => $value) {

        fwrite($open, $value);

    }

    fclose($open);

  * **Riga 67 (`fopen(..., "w");`):** Qui riapriamo il file, ma attenzione\! La modalità è `"w"` ("write"). A differenza di `"a"` (append), la modalità `"w"` **svuota completamente il file** prima di scrivere. È come cancellare la lavagna.

  * **Riga 68 (`foreach(...){ ... }`):** Facciamo un "ciclo" su tutti gli elementi *rimasti* nel nostro `$array_righi`.

  * **Riga 69 (`fwrite(...);`):** Riscriviamo ogni riga (ogni `$value`) nel file vuoto. La riga che avevamo distrutto con `unset` non c'è più, quindi non viene riscritta.

  * **Riga 71 (`fclose(...);`):** Chiudiamo il file. Abbiamo di fatto riscritto l'intero database, ma senza la riga che volevamo eliminare.

<!-- end list -->

    header("location: lettura.php");

    exit;

}

  * **Righe 73-74:** Come prima, reindirizziamo l'utente alla pagina di lettura.

### 4\. Blocco 3: MODIFICARE UNA RIGA

Se non stavamo scrivendo NÉ eliminando, si passa al terzo controllo.

/************************

 MODIFICARE UNA RIGA

*************************/

else if (isset($_POST['modifica']) && isset($_POST['row_update'])) {

  * **Riga 79:** "Altrimenti... controllo: mi sono arrivati dati via `POST` CHE contengono SIA un elemento `modifica` (il bottone "Salva modifiche") SIA un elemento `row_update`?".

      * `row_update` sarà probabilmente un campo nascosto (`<input type="hidden">`) nel form di modifica, che si porta dietro l'indice della riga che stiamo modificando.

<!-- end list -->

    $riga_da_modificare = $_POST['row_update'];

  * **Riga 81:** Recuperiamo l'indice della riga da aggiornare.

<!-- end list -->

    // 1. Riceviamo i 5 campi dal form di modifica

    $nome_cliente = str_replace($bad_char, "", $_POST['nome_cliente']);

    // ... (altri 4 campi) ...

    // 2. RICALCOLIAMO il totale (come da richiesta)

    $quantita_num = (float)$quantita;

    $prezzo_unitario_num = (float)$prezzo_unitario;

    $totale = $quantita_num * $prezzo_unitario_num;

  * **Righe 84-93:** Questa parte è **identica** al blocco di SCRITTURA. Riceviamo i dati (che ora sono quelli modificati), li puliamo, convertiamo i numeri e *ricalcoliamo* il totale.

<!-- end list -->

    // 3. Creiamo la nuova stringa (6 campi)

    $riga_modificata = $nome_cliente . $sep .

    // ... (concatenazione) ...

                       $totale . "\r\n";

  * **Righe 96-102:** Come nel blocco di SCRITTURA, creiamo la stringa della riga, ma questa volta con i dati *aggiornati*.

<!-- end list -->

    // 4. Sostituiamo la riga nell'array

    $array_righi = file($my_database_txt);

    $array_righi[$riga_da_modificare] = $riga_modificata; // Sostituzione

  * **Riga 105:** Come per l'ELIMINAZIONE, carichiamo tutto il file in un array.

  * **Riga 106:** Questa è la riga chiave della modifica\! Stiamo dicendo: "Prendi l'array, vai all'indice `$riga_da_modificare` e **sostituisci** il contenuto di quella cella con la nostra nuova `$riga_modificata`". Non stiamo distruggendo (unset), stiamo sovrascrivendo.

<!-- end list -->

    // 5. Riscriviamo l'intero file

    $open = fopen($my_database_txt, "w");

    foreach ($array_righi as $key => $value) {

        fwrite($open, $value);

    }

    fclose($open);

  * **Righe 109-114:** Esattamente come per l'eliminazione, svuotiamo il file (`"w"`) e lo riscriviamo da zero con il contenuto del nostro array, che ora contiene la riga modificata al posto giusto.

<!-- end list -->

    // 6. Ritorniamo alla pagina di visualizzazione

    header("location: lettura.php");

    exit;

}

  * **Righe 117-118:** E ancora, redirect alla pagina di lettura.

### 5\. Blocco 4: DEFAULT (Caso di errore)

```php

/************************

 DEFAULT (se nessuno script è chiamato)

*************************/

else {

    // Se action.php viene chiamato senza un motivo, rimanda a lettura.php

    header("location: lettura.php");

    exit;

}

?>

  * **Riga 123 (`else {`):** Questo è il blocco "paracadute". Se lo script `action.php` viene caricato senza `POST['scrivi']`, senza `GET['delete']` e senza `POST['modifica']` (per esempio, se un utente scrive `action.php` nella barra dell'indirizzo e basta)...

  * **Riga 125-126:** ...non facciamo nulla di pericoloso. Semplicemente, lo reindirizziamo alla pagina `lettura.php`. Questo evita che l'utente veda una pagina bianca e confusa.

  * **Riga 128 (`?>`):** Chiude il blocco di codice PHP.

Riepilogo per la classe

Questo file è un perfetto esempio di "controller". È un unico script che gestisce tre diverse azioni (Scrittura, Eliminazione, Modifica) controllando *come* è stato chiamato.

**Concetti chiave da ricordare:**

1.  **`$_POST` vs `$_GET`:** `POST` per i dati dei form (nascosti), `GET` per i dati nell'URL (visibili, come gli ID da eliminare).

2.  **File "append" (`a+`) vs "write" (`w`):** `"a+"` aggiunge in fondo. `"w"` svuota e riscrive da zero.

3.  **La "pulizia" (`str_replace`):** Non fidarsi mai dei dati dell'utente. Vanno sempre puliti prima di usarli.

4.  **Il "redirect" (`header`):** Dopo un'azione di successo, si reindirizza sempre l'utente a una pagina di visualizzazione, mai su una pagina bianca.


Commenti

Post popolari in questo blog

Esercizi in Excel e fogli di Google

Simulazioni di reti (con Cisco Packet Tracer)