PHPBlog.it

La questione dei tipi primitivi

Sappiamo tutti (oppure lo scoprite ora) che PHP non è un linguaggio fortemente tipizzato. Questo cosa vuol dire? Significa che non è necessario dichiarare il tipo di una variabile perchè essa possa gestire un particolar tipo di dato. In questo modo potremmo assegnare a $numero il valore 2 oppure “due” alla stessa maniera. Nei linguaggi fortemente tipizzati (C, Java…) è obbligatorio dichiarare il tipo di una variabile prima di assegnarle un valore, valore che chiaramente deve rispettare il tipo specificato.

Questo non significa certo che PHP non rispetti il concetto di tipo, ogni valore che possiamo assegnare ad una variabile ha un tipo che possiamo verificare attraverso delle utili funzioni per la gestione delle variabili. Avremo quindi la possibilità di utilizzare is_bool(), is_integer(), is_string()…per verificare il tipo di una variabile passata come parametro, in caso positivo il valore di ritorno sarà true.

Effettuare il controllo del tipo di una varibile torna particolarmente importante quando si ha a che fare con gli argomenti di metodi e funzioni, casi in cui bisogna prestare particolare attenzione al codice che si scrive. Vediamo un esempio. Immaginiamo di estrarre delle informazioni di configurazione da un file XML, l’elemento <resolvedomains> specifica all’applicazione se provare o meno ad eseguire il reverse DNS di un IP.

<settings>
<resolvedomains>false</resolvedomains>
<settings>

La stringa “false” viene letta dall’appliccazione e passata ad un metodo chiamato outputAddress() che si occupa di visualizzare i dati di un determinato IP.

[php]
function outputAddresses($resolve) {
foreach($this->addresses as $address) {
print $address;
if ($resolve) {
print “(“. gethostbyaddr($address) .”)”;
}
print “\n”;
}
}
[/php]

Il metodo outputAddresses() non fa altro che iterare su un array di indirizzi IP mostrandoli uno ad uno, nel caso in cui $resolve sia true il metodo restituisce anche il dominio assieme all’IP. Vediamo una porzione di codice che potrebbe essere chiamata da questo metodo:

$settings = simplexml_load_file("settings.xml");
$manager = new AddressManager();
$manager->outputAddresses($settings->resolvedomains);

Questo codice non si comporta come ci si aspetterebbe: passando la stringa “false” al metodo outputAddress() trascuriamo l’assunzione implicita che il metodo fa riguardo all’argomento passato. Infatti il metodo si aspetta un valore di tipo booleano (true o false) ma la stringa “false” corrisponde al valore true in un test. Questo è dato dal fatto che PHP esegue un cast di una stringa non vuota al valore booleano true in un test if. Di conseguenza:

if ("false") {
//..
}

è equivalente a

if (true) {
//..
}

Esistono diverse strade per risolvere questo problema, quella più metodica e sicura richiede di modificare il metodo outputAddress() per fare in modo che sia pronto ad aspettarsi il corretto tipo di dato riferito all’argomento $resolv.

[php]
function outputAddresses($resolve) {
if (!is_bool($resolve)) {
die(“outputAddress() richiede un argomento di tipo booleano\n”);
}
}
[/php]

Un approccio di questo tipo obbliga chi utilizza il metodo a fornire l’argomento $resolv nel tipo di dato corretto evitando problemi di ogni sorta. Detto questo sta al programmatore considerare il potenziale impatto che l’utilizzo di tipi inaspettati potrebbe avere sulla propria applicazione. Non pensate di lasciare nulla al caso, chi userà le vostre classi non può leggere quello che avete in mente quando le realizzate quindi è consigliabile pensare sempre come i metodi che scrivete possano reagire alla “spazzatura” che potrebbero ricevere in input.

Commenti

  • upnews.it scrive:

    La questione dei tipi primitivi…

    Sappiamo tutti (oppure lo scoprite ora) che PHP non è un linguaggio fortemente tipizzato. Questo cosa vuol dire? Significa che non è necessario dichiarare il tipo di una variabile perchè essa possa gestire un particolar tipo di dato. In questo modo …

  • Alessandro scrive:

    Oppure una buona soluzione è di scaricare un IDE open e settare le proprietà di ricerca delle variabile non istanziate…

    Ok io utilizzo Visual Studio con un plug-in per PHP. Ho questa soluzione non open ma sinceramente gli errori in fase di deploy sono calati drasticamente.

  • [...] costruttore si occupa appunto di costruire l’oggetto facendo le dovute verifiche sui tipi, di cui abbiamo parlato in un post precedente, ed agendo in base alla situazione che si [...]

  • Lascia un Commento

    *