Gestire il passaggio tra tipi di dato in PHP: conversioni, casting e controlli pratici

by theArchitect
SHARE
Gestire il passaggio tra tipi di dato in PHP: conversioni, casting e controlli pratici
© Guida-HTML5.it

Introduzione

In PHP le variabili sono flessibili: possono contenere numeri, stringhe, booleani, array e molti altri tipi di dato. Questa caratteristica è comoda, ma può creare errori sottili quando un valore cambia tipo in modo inatteso. Per esempio, una stringa ricevuta da un form può sembrare un numero, ma non sempre si comporta come tale in un’operazione matematica o in un confronto.

Un sotto-argomento molto utile, spesso sottovalutato, è proprio la conversione tra tipi di dato e il modo corretto di controllare e normalizzare i valori prima di usarli. Saper gestire casting, conversioni implicite e controlli di tipo è fondamentale per scrivere codice robusto, leggibile e meno soggetto a bug.

In questo tutorial vedremo un esempio concreto: la gestione di un ordine in un piccolo carrello e il calcolo del totale a partire da dati che arrivano come stringhe. Useremo controlli espliciti e conversioni mirate per evitare problemi tipici come somme sbagliate, confronti falsati o valori non validi.

Codice completo

<?php
declare(strict_types=1);

// Dati di esempio: simulano valori arrivati da un form o da un´API.
$prodotto = [
    ´nome´ => ´Tastiera meccanica´,
    ´prezzo´ => ´79.90´,   // stringa, non float
    ´quantita´ => ´2´,     // stringa, non int
    ´sconto´ => ´10´,      // percentuale come stringa
    ´disponibile´ => ´1´   // valore spesso ricevuto come stringa
];

// 1) Verifica preliminare dei dati
if (!isset($prodotto[´nome´], $prodotto[´prezzo´], $prodotto[´quantita´])) {
    die(´Dati prodotto incompleti.´);
}

// 2) Normalizzazione dei tipi
$nome = trim((string) $prodotto[´nome´]);
$prezzo = (float) $prodotto[´prezzo´];
$quantita = (int) $prodotto[´quantita´];
$sconto = isset($prodotto[´sconto´]) ? (float) $prodotto[´sconto´] : 0.0;
$disponibile = filter_var($prodotto[´disponibile´] ?? false, FILTER_VALIDATE_BOOL);

// 3) Controlli di validità
if ($nome === ´´) {
    die(´Il nome del prodotto non può essere vuoto.´);
}

if ($prezzo <= 0) {
    die(´Il prezzo deve essere maggiore di zero.´);
}

if ($quantita <= 0) {
    die(´La quantità deve essere maggiore di zero.´);
}

if ($sconto < 0 || $sconto > 100) {
    die(´Lo sconto deve essere compreso tra 0 e 100.´);
}

// 4) Calcolo del totale
$totaleLordo = $prezzo * $quantita;
$totaleScontato = $totaleLordo - ($totaleLordo * $sconto / 100);

// 5) Formattazione finale
$totaleLordoFormattato = number_format($totaleLordo, 2, ´,´, ´.´);
$totaleScontatoFormattato = number_format($totaleScontato, 2, ´,´, ´.´);
$prezzoFormattato = number_format($prezzo, 2, ´,´, ´.´);

// 6) Output
echo "<h1>Riepilogo ordine</h1>";
echo "<p>Prodotto: " . htmlspecialchars($nome) . "</p>";
echo "<p>Prezzo unitario: € " . $prezzoFormattato . "</p>";
echo "<p>Quantità: " . $quantita . "</p>";
echo "<p>Sconto: " . $sconto . "%</p>";
echo "<p>Disponibile: " . ($disponibile ? ´Sì´ : ´No´) . "</p>";
echo "<p>Totale lordo: € " . $totaleLordoFormattato . "</p>";
echo "<p>Totale scontato: € " . $totaleScontatoFormattato . "</p>";

// 7) Esempio di confronto corretto
$codice = ´010´;
if ($codice === ´10´) {
    echo "<p>Codice identico in stringa.</p>";
} else {
    echo "<p>Confronto stretto: ´010´ non è uguale a ´10´.</p>";
}

// 8) Esempio di conversione esplicita utile
$numeroOrdine = ´42´;
$numeroOrdineIntero = (int) $numeroOrdine;

echo "<p>Numero ordine come intero: " . $numeroOrdineIntero . "</p>";
?>

Spiegazione

Il punto centrale di questo esempio è semplice: non fidarti del tipo di dato solo perché il valore “sembra giusto”. In PHP, molti dati arrivano come stringhe, soprattutto da form HTML, query string, file JSON o chiamate API. Se non li converti in modo esplicito, rischi di ottenere risultati inattesi.

1. strict_types aiuta a prevenire errori

La direttiva declare(strict_types=1); rende più rigoroso il comportamento delle funzioni tipizzate. Non elimina tutti i problemi, ma aiuta a intercettare passaggi di tipo poco chiari. È una buona pratica quando vuoi scrivere codice più affidabile.

2. Casting esplicito

Nel codice abbiamo usato conversioni esplicite:

  • (string) per garantire che il nome sia trattato come stringa;
  • (float) per il prezzo, utile nei calcoli con decimali;
  • (int) per la quantità, che deve essere un numero intero;
  • filter_var(..., FILTER_VALIDATE_BOOL) per convertire correttamente valori tipo ´1´, ´true´, ´on´ o equivalenti in booleano.

Il casting è utile quando sai già che il dato è valido, ma vuoi normalizzarlo in un tipo preciso prima di operare.

3. Validazione prima dell’uso

Non basta convertire: bisogna anche validare. Per questo controlliamo che:

  • il nome non sia vuoto;
  • il prezzo sia maggiore di zero;
  • la quantità sia positiva;
  • lo sconto sia compreso tra 0 e 100.

Questo passaggio evita errori logici. Ad esempio, una quantità negativa non ha senso in un ordine, anche se tecnicamente PHP la può rappresentare come intero.

4. Differenza tra confronto stretto e confronto debole

Nel blocco finale abbiamo inserito un esempio sul codice ´010´. In PHP, usare === significa confrontare valore e tipo. Quindi ´010´ === ´10´ restituisce falso, perché le stringhe non sono identiche.

Questo è molto importante: i confronti deboli con == possono produrre risultati ambigui, soprattutto quando entrano in gioco stringhe numeriche, booleani o valori nulli. In generale, per codice moderno e leggibile, è meglio preferire il confronto stretto.

5. Formattazione dei numeri

Per mostrare il totale usiamo number_format(). Questo non cambia il tipo del valore interno, ma rende l’output più adatto alla lettura umana. È una distinzione importante:

  • tipo interno: float o int, usato per i calcoli;
  • formato di output: stringa leggibile, usata per la visualizzazione.

Separare questi due aspetti è una buona abitudine professionale.

Best practice

  • Converti i dati appena entrano nel sistema: ad esempio subito dopo aver ricevuto un input da form, API o file.
  • Valida prima di calcolare: non dare per scontato che un valore sia corretto solo perché è stato convertito.
  • Usa confronti stretti con === e !== per evitare conversioni implicite imprevedibili.
  • Non abusare del casting: se un dato non è affidabile, meglio bloccarlo con un controllo chiaro invece di forzarlo.
  • Tratta separatamente logica e presentazione: i numeri servono per i calcoli, le stringhe formattate per l’output.
  • Proteggi l’output HTML con htmlspecialchars() quando stampi dati esterni, anche se il focus del tutorial è sui tipi di dato.
  • Preferisci tipi coerenti nelle tue funzioni: se una funzione riceve un intero, falli arrivare come intero, non come stringa numerica.

Riepilogo

Gestire bene il passaggio tra tipi di dato in PHP è una competenza pratica essenziale. In questo tutorial abbiamo visto come:

  • convertire esplicitamente stringhe in numeri e booleani;
  • validare i dati prima di usarli;
  • distinguere tra confronto stretto e confronto debole;
  • separare i dati usati nei calcoli dal formato usato in output.

Il messaggio più importante è questo: i bug più fastidiosi spesso nascono da dati “quasi corretti” ma del tipo sbagliato. Con pochi accorgimenti puoi rendere il tuo codice molto più affidabile e facile da mantenere.

Approfondisci con risorse ufficiali

  • PHP Manual - Types: documentazione ufficiale sui tipi di dato in PHP
  • PHP Manual - Type Juggling: comportamento delle conversioni implicite
  • PHP Manual - Type Declarations: dichiarazioni di tipo per parametri, ritorni e proprietà
  • PHP Manual - filter_var(): validazione e filtraggio dei dati
  • PHP Manual - strict_types: uso della modalità rigorosa nei file PHP

SHARE