Salve a tutti,
stavo lavorando ad una gestione degli errori in PHP 4 che assomigli alle eccezioni (presenti in PHP5)e credo che stia venendo fuori qualcosa di carino
La gestione degli errori in PHP4 è abbastanza insoddisfacente, di solito si fa così
if(!operazione)
{
//fai qualcosa per l'errore
}
elseif(!altraoperazione)
{
//fai qualcosa per l'errore
}
etc.etc.
Una serie di controlli che vanno ripetuti ogni volta che si incapsulano le operazioni in un'altra funzione o classe
Oppure si usa il sistema "ufficiale" di php4 con le funzioni trigger_error e set_error_handler, che però rispetto alle eccezioni ha il difetto di non consentire al programmatore di individuare gli errori per tipologia (es. errore di connessione, errore nella query, altra "malattia" dello script)
http://www.php.net/set_error_handler
Ispirandomi ad actionscript ho tirato fuori questa robbba, che trovo abbastanza comoda per intercettare gli errori
Eccola applicata ad un esempio con FTP
function ftpError($message, $id, &$sender)
{
//qui dentro gestisco l'errore come mi pare
//qui sotto solo un esempio di ciò che accade all'interno
$args= func_get_args() ;
print_r($args) ;
}
function getError($message, $id, &$sender)
{
//qui dentro gestisco l'errore come mi pare
//qui sotto solo un esempio di ciò che accade all'interno
$args= func_get_args() ;
print_r($args) ;
}
function getOk($message, $id, &$sender)
{
//qui dentro gestisco l'errore come mi pare
//qui sotto solo un esempio di ciò che accade all'interno
$args= func_get_args() ;
print_r($args) ;
}
$ftp = new FTPhandler() ;
/*anzichè una funzione
al posto di ftpError posso mettere array($oggetto, 'metodo') oppure
array('nomeclasse', 'metodo')
*/
$ftp->addEventListener('onError', 'ftpError') ;
$dns = array
(
'host'=>'',
'user'=>'',
'pass'=>'',
'port'=>21
) ;
$conn = $ftp->open($dns, true);
/*anzichè una funzione
al posto di getError e getOk posso mettere array($oggetto, 'metodo') oppure
array('nomeclasse', 'metodo')
*/
$conn->addEventListener('onError', 'getError') ;
$conn->addEventListener('onGetComplete', 'getOk') ;
$conn->getBinary('pippo1.zip', './dir/miofileremoto1.zip') ;
$conn->getBinary('pippo2.zip', './dir/miofileremoto2.zip') ;
$conn->getBinary('pippo3.zip', './dir/miofileremoto3.zip') ;
$conn->getBinary('pippo4.zip', './dir/miofileremoto4.zip') ;
$conn->getBinary('pippo5.zip', './dir/miofileremoto5.zip') ;
$conn->getBinary('pippo6.zip', './dir/miofileremoto6.zip') ;
$conn->close() ;
Qui sotto le classi
<?php
class EventDispatcher
{
//array associativo che contiene gli eventi
var $events ;
function EventDispatcher()
{
$this->events = array();
}
/*
Genera l'evento: $eventName è una stringa che identifica l'evento (es. onError)
*/
function dispatchEvent($eventName, $eventId, $eventMessage)
{
$args = func_get_args() ;
//Passo un riferimento all'oggetto che invia l'evento
$args[] = &$this ;
$eventName = array_shift($args);
/*
Impedisce errori nel caso in cui non sia stato previsto alcun listener
per l'evento
*/
if(!isset($this->events[$eventName]))
{
return ;
}
call_user_func_array($this->events[$eventName], $args) ;
}
/*
- $eventName è una stringa che identifica l'evento (es. onError)
- $handler può essere una stringa (nome funzione) o
un array ( array(oggetto, 'metodo') e anche
array('classe', 'metodo_statico') )
*/
function addEventListener($eventName, $handler)
{
$this->events[$eventName] = $handler ;
}
function removeEventListener($eventName)
{
unset($this->events[$eventName]) ;
}
}
class FTPhandler extends EventDispatcher
{
function FTPhandler()
{
parent::EventDispatcher() ;
}
function open($dns, $passive = false, $timeout=30)
{
$link = ftp_connect(
$dns['host'] ,
$dns['port'] ,
$timeout
) ;
if(!$link)
{
$this->dispatchEvent('onError', "Connessione a {$server} fallita", 'CONN_FAILED') ;
}
elseif(!ftp_login($link, $dns['user'], $dns['pass']))
{
$this->dispatchEvent('onError', "Login fallito (user:{$dns['user']}, pass:{$dns['pass']}) ", 'LOGIN_FAILED') ;
}
elseif($passive && !ftp_pasv($link, $passive))
{
$this->dispatchEvent('onError', "Impossibile settare la modalità FTP passiva", 'SET_PASV_FAILED' ) ;
}
return(new FTPlink($link, $dns)) ;
}
}
class FTPlink extends EventDispatcher
{
var $link ;
var $dns ;
function FTPlink($link, $dns)
{
parent::EventDispatcher() ;
$this->link = $link ;
$this->localSaveDir = './' ;
$this->overwrite = false ;
$this->dns = $dns ;
}
function localSavePath($dir)
{
$this->localSaveDir = $dir ;
}
function setOverwrite($what=true)
{
$this->overwrite = $what ;
}
function _get($localFileName, $remoteFile, $type)
{
$localSavePath = str_replace('//', '/', $this->localSaveDir.'/'.basename($remoteFile)) ;
$remoteList = ftp_nlist($this->link, dirname($remoteFile)) ;
if(!$remoteList)
{
$this->dispatchEvent('onError', "Impossibile ottenere la lista dei file remoti in {$remote}", 'FTP_NLIST_FAILED') ;
}
elseif (!in_array($remoteFile, $remoteList) ) {
$this->dispatchEvent('onError', "Il file remoto {$remoteFile} non esiste", 'FTP_NO_FILE') ;
}
elseif(!is_writable($this->localSaveDir))
{
$this->dispatchEvent('onError', "La directory {$this->localSaveDir} non è scrivibile", 'FTP_NO_WRITE_PERMS') ;
}
elseif(!$this->overwrite && file_exists($localSavePath))
{
$this->dispatchEvent('onError', "Il file {$localSavePath} già esiste", 'FTP_FILE_EXISTS') ;
}
else if (! ftp_get($this->link, $localSavePath, $remoteFile, $type) ) {
$this->dispatchEvent('onError', "Impossibile prelevare e salvare il file {$remoteFile}", 'FTP_GET_FAILED') ;
}
else
{
$this->dispatchEvent('onGetComplete', "{$remoteFile} scaricato correttamente", 'FTP_GET_OK') ;
}
}
//END _get
function getBinary($local, $remote)
{
$this->_get($local, $remote, FTP_BINARY) ;
}
//END function
function getAscii($local, $remote)
{
$this->_get($local, $remote, FTP_ASCII) ;
}
//END function
function close()
{
if(!ftp_close($this->link))
{
$this->dispatchEvent('onError', "Errore nella chiusura della connessione a {$this->dns['host']}", 'FTP_CLOSE_FAILED') ;
}
}
}
?>