26 Mar 2011 0 commenti
L'operatore di silence @ può precedere un'istruzione e consente di annullare la rilevazione degli errori che questa può eventualmente generare. Occorre evidenziare che la mancata rilevazione dell'errore non significa che questo non si sia comunque verificato con tutte le conseguenze che da esso derivano: ad esempio in caso di fatal error anche se non comparirà nulla a video lo script comunque si interromperà.
Esso non può essere anteposto a istruzioni quali: definizioni di classi o funzioni, operatori condizionali if else, o cicli (foreach, for, etc).
USO E ABUSO
L'utilizzo di tale operatore deve essere un'evenienza eccezionale, legata a ragioni specifiche e opportunamente gestita. Inoltre un suo uso improprio potrebbe rendere difficile il debug dei nostri script. Molto spesso, invece, lo si vede impiegato anche in ambiti che sono del tutto fuoriluogo.
Uno dei casi maggiormente gravi si ha con le inclusioni:
<?php @include('file.php'); ?>
Questo tipo di utilizzo espone a forti rischi: infatti, non solo verrà rilevato il warning in caso di file non trovato, ma verranno "soppressi" anche gli errori presenti nel file incluso. Per cui ciò è da evitare sempre.
USO CORRETTO
Non è possibile fissare regole rigide di un suo corretto utilizzo e vi può essere un diverso approccio all'utilizzo dell'operatore silence.
Un primo caso in cui potrebbe essere impiegato è legata ad istruzioni la cui mancata esecuzione non compromettono il regolare funzionamento dello script. Ad esempio la funzione ini_set() serve per modificare al volo (run-time) impostazioni del php.ini: molto spesso i servizi di hosting disabilitano tale funzione per alcuni settaggi del php.ini, ma ciò, alle volte, non impedisce ai nostri script di funzionare ugualmente in modo corretto.
Un ulteriore tale caso potrebbe essere legato ad eventi non dipendenti da procedura interne allo script, quali ad esempio il down del server. Si tratta di casi relativamente sporadici.
In genere, gli errori devono essere resi comunque "controllabili": un caso classico è con le funzioni legate ad interazioni con mysql nel cui ambito possiamo far ricorso alla funzione mysql_error() e conoscere i motivi per i quali un'interazione con il database fallisce.
$connect = @mysql_connect('localhost', 'my_user', 'my_password'); if (!$connect) { die('Connessione fallita: ' . mysql_error()); } $select = @mysql_select_db('my_database', $connect); if (!$select) { die('Selezione database fallita: ' . mysql_error()); } $query = "SELECT * FROM tabella"; $result = @mysql_query($query, $connect) or die(mysql_error());
In questo esempio, nonostante le @ apposte alle diverse funzioni coinvolte abbiamo totale riscontro di tutti gli errori, nonchè interrompendo lo script con die() evitaimo il verificarsi di errori "a cascata".
Tuttavia, non sempre è necessario interrompere lo script: nel precedente esempio ciò si rendeva necessario in quanto il successo di ogni istruzione constituiva presupposto per le successive.
Fra i tanti casi in cui non occorre interrompere lo script vediamo quello con la funzione mail(). Essa fallisce in caso di mancanza dei parametri necessari o mancata errata configurazione (si rimanda al manuale ufficiale). Vediamo quindi come gestire questa evenienza:
<?php if(@!mail('destinatario@dominio.it', 'Oggetto email', 'testo email')) { echo 'Invio email fallito.'; } else { echo 'Email inviata con successo.'; }
Anche in questo caso abbiamo totale controllo sullo script dato che sarà palesato il fallimento dell'invio, ma non si è reso necessario l'interruzione dello script data l'assenza di possibili errori a cascata.
In molti casi, inoltre, l'uso dell'operatore di silence potrebbe essere evitato se vengono fatti i dovuti controlli preventivi.
$numero = 20; $divisore = 0; if($divisore==0) { echo 'non è possibile effettuare la divisione con un divisore pari a zero'; } else { $divisione = $numero/$divisore; }
Sempre con riferimento ai controlli preventivi da effettuare pensiamo, a puro titolo esemplificativo, al trittico di funzioni fopen, fwrite, e fclose.
La funzione fopen genera un warning nel caso l'apertura del file fallisce e lo stesso manuale ufficiale suggerisce che si potrebbe usare l'operatore @ per sopprimere il warning. Tuttavia, il fallimento di fopen può derivare (e nella maggior parte dei casi è così) dal fatto il file non esiste (o il percorso è errato) o che non abbia i permessi.
La funzione fwrite, invece, genera un warning nel caso in cui non gli è stato passata la risorsa (fallimento di fopen) o nel caso in cui il file non abbia i permessi.
In questo scenario l'operatore @ può essere opportuno utilizzarlo ma con alcune cautele preventive. Vediamo come:
$MyFile = "file.txt"; $text = "test script"; if(!is_file($MyFile)){ echo 'file non essitente'; } else if(!is_writable($MyFile)){ echo 'file privo dei permessi di scrittura'; } else { $handle = @fopen($MyFile, 'w') or die('Apertura file fallita'); @fwrite($handle, $text) or die('Scrittura file fallita'); fclose($handle); echo 'Scrittura del file eseguita con successo'; }
Gazie alla funzioni is_file() e is_writable() abbiamo preventivamente verificato l'esistenza del file e i permessi di scrittura avendo così pieno controllo sul nostro script.
Ovviamente si tratta di semplici esempi volti a esprimere un concetto più ampio: prima di applicare una funzione che potenzialmente può generare un errore è opportuno eseguire controlli preventvi sulla validità dei parametri, soprattutto se questi sono di natura dinamica.
Olimpio Romanella
Sono un appassionato di Web Developing con un particolare debole per php. Mi dedico principalmente dello sviluppo back-end ed in particolare programmazione lato server con php, sviluppo di database relazionali MySql e progettazione di CMS di piccole e medie dimensioni.
Mi avvalgo del framework javascript Jquery, utilizzando molti dei suoi plugin e nei dei miei progetti utilizzo spesso il framework MVC Codeigniter.