PHP: tipizzazione delle variabili con valori null, booleani e numerici

by theArchitect
SHARE
PHP: tipizzazione delle variabili con valori null, booleani e numerici
© Guida-HTML5.it

Introduzione

Quando si parla di variabili e tipi di dato in PHP, spesso ci si concentra su concetti molto ampi come array, oggetti o conversioni implicite. Un sotto-argomento particolarmente utile, però, è la gestione pratica dei valori null, booleani e numerici nei flussi applicativi reali.

Questi tre tipi di dato sono tra i più usati in qualunque progetto PHP: servono per rappresentare stati opzionali, verifiche logiche, prezzi, quantità, punteggi, età, soglie e risultati di operazioni. Capire come trattarli correttamente evita bug sottili, controlli errati e comportamenti inattesi, soprattutto quando i dati arrivano da form, API o database.

In questo tutorial vedremo un esempio concreto: la validazione e il calcolo di un ordine e-commerce, dove alcuni campi possono essere assenti, altri devono essere interpretati come vero/falso, e altri ancora devono essere trattati come numeri affidabili.

Codice completo

<?php

declare(strict_types=1);

/**
 * Esempio pratico:
 * - $couponCode può essere null se l´utente non inserisce alcun codice
 * - $isMember indica se il cliente ha diritto a uno sconto
 * - $quantity e $price sono dati numerici che arrivano come input e vanno validati
 */

$couponCode = null;
$isMember = true;
$quantity = 3;
$price = 19.90;
$shippingCost = 4.99;

/**
 * Simuliamo un input esterno, ad esempio da un form.
 * In un´app reale questi valori potrebbero arrivare da $_POST o da una API.
 */
$rawQuantity = ´3´;
$rawPrice = ´19.90´;
$rawCouponCode = ´´;
$rawIsMember = ´1´; // tipico valore proveniente da checkbox o select

// Normalizzazione del coupon: stringa vuota => null
$couponCode = ($rawCouponCode !== ´´) ? trim($rawCouponCode) : null;

// Conversione del flag membro in booleano
$isMember = filter_var($rawIsMember, FILTER_VALIDATE_BOOL, FILTER_NULL_ON_FAILURE);
if ($isMember === null) {
    die(´Valore non valido per isMember´);
}

// Validazione della quantità: deve essere un intero positivo
$quantity = filter_var($rawQuantity, FILTER_VALIDATE_INT);
if ($quantity === false || $quantity <= 0) {
    die(´La quantità non è valida´);
}

// Validazione del prezzo: deve essere numerico e maggiore di zero
if (!is_numeric($rawPrice)) {
    die(´Il prezzo non è numerico´);
}
$price = (float) $rawPrice;

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

// Calcolo del subtotale
$subtotal = $quantity * $price;

// Sconto base per i membri
$discount = 0.0;
if ($isMember) {
    $discount = $subtotal * 0.10;
}

// Sconto coupon opzionale
if ($couponCode !== null) {
    // Esempio semplice: il coupon "SAVE5" applica 5 euro di sconto
    if ($couponCode === ´SAVE5´) {
        $discount += 5.00;
    }
}

// Evitiamo che lo sconto superi il subtotale
if ($discount > $subtotal) {
    $discount = $subtotal;
}

$total = $subtotal - $discount + $shippingCost;

// Output leggibile
echo "Riepilogo ordinen";
echo "Quantità: {$quantity}n";
echo "Prezzo unitario: " . number_format($price, 2, ´,´, ´.´) . " EURn";
echo "Subtotale: " . number_format($subtotal, 2, ´,´, ´.´) . " EURn";
echo "Sconto: " . number_format($discount, 2, ´,´, ´.´) . " EURn";
echo "Spedizione: " . number_format($shippingCost, 2, ´,´, ´.´) . " EURn";
echo "Totale: " . number_format($total, 2, ´,´, ´.´) . " EURn";

/**
 * Funzione di supporto: mostra come distinguere tra null, boolean e numeri
 */
function describeValue(mixed $value): string
{
    if (is_null($value)) {
        return ´Valore nullo´;
    }

    if (is_bool($value)) {
        return $value ? ´Booleano true´ : ´Booleano false´;
    }

    if (is_int($value)) {
        return ´Intero´;
    }

    if (is_float($value)) {
        return ´Numero decimale´;
    }

    return ´Altro tipo´;
}

echo "n--- Diagnostica tipi ---n";
echo describeValue($couponCode) . "n";
echo describeValue($isMember) . "n";
echo describeValue($quantity) . "n";
echo describeValue($price) . "n";

?>

Spiegazione

Il codice mostra un caso d’uso molto comune: ricevere dati esterni e trasformarli in valori affidabili prima di usarli nei calcoli. Questo è un passaggio fondamentale in PHP perché i dati in ingresso non sono quasi mai già pronti per la logica applicativa.

1. Il ruolo di null

Il valore null rappresenta l’assenza di un dato. Nel nostro esempio, il coupon può non essere inserito dall’utente. Invece di lasciare una stringa vuota, convertiamo il valore in null:

  • stringa vuota = nessun dato utile
  • null = campo assente in modo esplicito

Questa scelta rende il codice più chiaro. Quando controlliamo $couponCode !== null, sappiamo che il dato esiste davvero e possiamo applicare eventuali regole.

2. Gestire i booleani in modo sicuro

In PHP, i booleani possono essere insidiosi quando arrivano come stringhe. Per esempio, un checkbox HTML può inviare ´1´, ´on´ o valori simili. Per questo usiamo filter_var(..., FILTER_VALIDATE_BOOL) con FILTER_NULL_ON_FAILURE.

Questo approccio è utile perché distingue tre casi:

  • true se il valore rappresenta davvero vero
  • false se il valore rappresenta davvero falso
  • null se il valore non è interpretabile

È molto meglio di un semplice cast a booleano, che potrebbe trasformare in true anche valori non desiderati.

3. Validare i numeri prima dei calcoli

La quantità deve essere un intero positivo, mentre il prezzo deve essere numerico e maggiore di zero. Qui distinguiamo due livelli:

  • validazione: controllare che il dato abbia senso
  • conversione: trasformare il dato nel tipo adatto

Per la quantità usiamo FILTER_VALIDATE_INT, che è più robusto di un cast diretto. Per il prezzo, invece, verifichiamo prima con is_numeric() e poi convertiamo in float.

Questo ordine è importante: se convertissi subito un valore non valido, rischieresti di ottenere 0 o un numero errato, nascondendo il problema invece di intercettarlo.

4. Perché usare declare(strict_types=1)

La direttiva declare(strict_types=1) rende più rigoroso il comportamento delle funzioni e aiuta a evitare conversioni automatiche troppo permissive. In un progetto moderno, è una buona abitudine perché rende più prevedibile il codice.

Non elimina tutti i problemi di tipizzazione, ma ti aiuta a intercettare prima gli errori e a scrivere funzioni con contratti più chiari.

5. Funzione di diagnostica dei tipi

La funzione describeValue() mostra un pattern utile: controllare il tipo di dato con funzioni come is_null(), is_bool(), is_int() e is_float(). Questo è molto comodo quando devi fare debug o quando vuoi costruire log più leggibili.

In pratica, invece di assumere che un valore sia già corretto, lo interroghi in modo esplicito. È un’abitudine che aiuta molto nei progetti reali, soprattutto quando i dati passano tra più livelli dell’applicazione.

Best practice

  • Tratta i dati esterni come non affidabili: form, query string, API e file devono sempre essere validati.
  • Usa null per i campi opzionali: è più chiaro di stringhe vuote o valori fittizi.
  • Non fidarti dei cast automatici: possono mascherare errori logici e produrre risultati inattesi.
  • Valida prima di calcolare: soprattutto per quantità, importi, percentuali e soglie.
  • Preferisci funzioni di validazione dedicate: come filter_var(), is_numeric() e i controlli espliciti con is_bool().
  • Usa nomi di variabile chiari: $rawPrice e $price indicano bene la differenza tra input grezzo e dato normalizzato.
  • Gestisci gli errori subito: se un dato non è valido, interrompi il flusso o restituisci un messaggio preciso.

Riepilogo

In questo tutorial abbiamo visto come gestire in modo pratico tre tipi di dato fondamentali in PHP: null, boolean e numerici. Il punto chiave non è solo conoscere i tipi, ma sapere come usarli correttamente quando i dati arrivano dall’esterno.

Abbiamo costruito un esempio realistico di ordine e-commerce per mostrare un flusso completo:

  • normalizzazione di un campo opzionale con null
  • conversione sicura di un flag in boolean
  • validazione di quantità e prezzo come valori numerici
  • calcolo finale con controlli sulle soglie

Se applichi questi principi nei tuoi progetti, il codice diventa più robusto, leggibile e facile da mantenere.

Approfondisci con risorse ufficiali

  • PHP Manual - Types: https://www.php.net/manual/en/language.types.php
  • PHP Manual - NULL: https://www.php.net/manual/en/language.types.null.php
  • PHP Manual - Booleans: https://www.php.net/manual/en/language.types.boolean.php
  • PHP Manual - Integers: https://www.php.net/manual/en/language.types.integer.php
  • PHP Manual - Floats: https://www.php.net/manual/en/language.types.float.php
  • PHP Manual - filter_var(): https://www.php.net/manual/en/function.filter-var.php
  • PHP Manual - is_numeric(): https://www.php.net/manual/en/function.is-numeric.php

SHARE