Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

PHP e tipizzazione delle costanti di classe

PHP nasce come linguaggio a tipizzazione debole. Cosa cambia con la tipizzazione delle costanti di classe?
PHP nasce come linguaggio a tipizzazione debole. Cosa cambia con la tipizzazione delle costanti di classe?
Link copiato negli appunti

Tra le critiche che vengono mosse più di frequente a PHP vi è quella riferita al fatto che si tratta di un linguaggio debolmente tipizzato (loosely typed). Nel corso del tempo, e delle varie release, gli sviluppatori sono intervenuti per migliorare la tipizzazione in PHP ma, anche perché siamo ben lontani dal poterlo definire un linguaggio a tipizzazione forte, la sua natura rimane in buona parte quella delle origini. Per conoscere quale sia lo stato dell'arte del linguaggio in termini di tipizzazione partiamo con il capire a cosa si riferisce questo concetto.

Cos'è la tipizzazione?

Nella programmazione, ma anche nello sviluppo per il Web, la tipizzazione definisce il modo in cui un linguaggio classifica valori ed espressioni sulla base di tipi di dato differenti. Se "php" è plausibilmente un tipo di dato stringa, "3" può essere ad esempio sia una stringa che un numero intero, confronto che da solo fa emergere le possibili ambiguità di tipizzazione imprecisa. Con essa un linguaggio determina come i valori possono essere impiegati nelle operazioni: è possibile sommare due numeri interi, due decimali o un intero e un decimale ma non due stringhe che però possono essere concatenate.

Non esiste un solo tipo (o "politica") di tipizzazione. Una prima distinzione riguarda per esempio la differenza tra tipizzazione statica e dinamica. Nel primo caso i tipi di tutte le variabili sono conosciuti al momento della compilazione, si pensi per esempio a Java, mentre nel secondo sono noti solo a runtime, come accade in Python. La tipizzazione può essere poi implicita o esplicita. È implicita quando il tipo di dato associato ad una variabile viene dedotto in fase di compilazione sulla base del valore che è stato assegnato. È esplicita quando il tipo deve essere invece specificato durante il coding.

Un'ultima distinzione, quella che ci interessa di più in questo momento, riguarda la differenza tra tipizzazione forte e debole. Con la tipizzazione forte non sono consentite operazioni tra tipi incompatibili senza che venga effettuata esplicitamente una conversione da un tipo a quello che garantisce, appunto, la compatibilità con l'altro operatore. Con la tipizzazione debole sono permesse le operazioni tra tipi di natura differente e la loro conversione avviene spesso automaticamente. La tipizzazione debole è svantaggiosa? Non in senso assoluto. Rende però il codice meno leggibile e può influire negativamente sulle performance. In PHP, ad esempio, per poter ricavare il tipo delle variabili è spesso necessario ricorrere a funzioni specifiche come gettype().

Vi è poi un discorso riguardante la sicurezza. In alcuni casi infatti la tipizzazione debole potrebbe facilitare il passaggio di valori arbitrati alle espressioni. Questo perché potrebbero verificarsi degli errori di tipo che non vengono rilevati.

PHP e tipizzazione debole

Perché PHP è considerato un linguaggio a tipizzazione debole? Una prima spiegazione è data dal fatto che in PHP le assegnazioni ai tipi sono flessibili. Più precisamente in questo linguaggio la dichiarazione esplicita del tipo delle variabili non è necessaria. Questo significa anche che, data una variabile, si può avere l'assegnazione a tipi di dato differenti e in momenti diversi mentre viene eseguita un'applicazione.

In secondo luogo, in PHP i tipi delle variabili possono cambiare in base al contesto, cioè automaticamente. Ciò succede ad esempio quando si prova a sommare il valore di una stringa e quello di un numero. L'interprete del linguaggio cercherà infatti di convertire la stringa in un numero per completare l'operazione richiesta.

L'ultimo punto da approfondire è quello della coercion o conversione implicita di tipo. Essa può avvenire quando si effettuano delle operazioni tra tipi di dato differenti. Si pensi al caso di un confronto tra una stringa e un numero che PHP può rendere possibile convertendo autonomamente uno dei due valori.

PHP e tipizzazione delle proprietà

Per capire quanto si sia evoluto il supporto alla tipizzazione in PHP dobbiamo fare riferimento innanzitutto al concetto di type hint che si ricollega alla dichiarazione del tipo di argomento. Grazie ad esso possiamo definire esplicitamente il tipo di dato assegnato ad una variabile da passare ad un metodo di classe o a una funzione. Questa dichiarazione venne introdotta per la prima volta nella versione 5 e con la 7.2 vi fu un'estensione al tipo object. Con la release 7.4 si poterono invece dichiarare i tipi di proprietà first-class:

class Dho {
    public string $nome;
    public int $anni;
    // Costruttore con dichiarazioni di tipo
    public function __construct(string $nome, int $anni) {
        $this->nome = $nome;
        $this->anni = $anni;
    }
    // Restituzione di una stringa con nome ed età
    public function mostraDati(): string {
        return "Nome: {$this->nome}, Anni: {$this->anni}";
    }
}
// Oggetto Dho con specifiche di tipo
$dho = new Dho("Home Simpson", 39);
// Stampa a video dell'output
$dho_data = $dho->mostraDati();
echo $dho_data;

Questo non è stato l'unico passo avanti a favore di un rafforzamento della tipizzazione in PHP. Una novità ancora più interessante è arrivata infatti con la versione 8.3 e la tipizzazione delle costanti di classe.

PHP e tipizzazione delle costanti di classe

Prima di PHP 8.3 non era possibile dichiarare tipi per le costanti di classe. Ciò non rappresentava un problema particolarmente grave per le globali, nelle costanti di classe poteva essere invece fonte di errori e confusione per gli sviluppatori. Come impostazione predefinita le classi figlie possono effettuare l'override delle costanti delle classi madre, quindi senza tipizzazione era difficile stabilire quale fosse il vero tipo di una costante di classe. Ad esempio con:

interface Springfield {
    const LISA = "Lisa";
}

potremmo pensare che LISA è una stringa. In realtà essa potrebbe essere, ad esempio, un array:

class Simpson implements Springfield {
    const LISA = [];
}

Con la tipizzazione delle costanti di classe abbiamo invece:

interface Springfield {
    const string LISA = "Lisa";
}

In questa espressione il tipo dichiarato e il valore sono entrambi delle stringhe e la sintassi utilizzata risulta valida. Questa opportunità di tipizzazione diventa ancora più interessante nel caso delle classi derivate. Una classe figlia ha infatti la possibilità di assegnare ad una costante un nuovo valore differente da quello dichiarato inizialmente per essa. Con la tipizzazione delle costanti di classe abbiamo però la conservazione del tipo, cosa che permette di evitare eventuali incompatibilità. Data infatti una dichiarazione come questa:

class UnoQualsiasi {
    const string NOME = "Marge Simpson";
}

possiamo estendere la classe in questo modo:

class AncoraUnoQualsiasi extends UnoQualsiasi {
    const string NOME = "Bart Simpson";
}

Il valore può quindi essere modificato se il tipo corrisponde a quello utilizzato nella dichiarazione della classe base. Nella derivata non si può invece utilizzare:

const NOME = "Bart Simpson";

perché il tipo è stato specificato per la classe base e deve rimanere tale. Non si può inoltre modificare il tipo dichiarato nella classe base anche se il valore utilizzato è compatibile con il tipo che si vorrebbe assegnare.

Ti consigliamo anche