2012-11-13 14 views
5

Quando si utilizza filesystem functions, quale sarebbe il modo corretto di errori di manipolazione quali:Qual è il modo corretto di gestire gli errori e gli avvertimenti sulle funzioni del filesystem in PHP?

Attenzione: link simbolico(): No such file or directory in /path-to-script/symlink.php on line XXX

Il mio approccio abituale è quello di verificare qualsiasi condizione che possa produrre un errore prima di chiamare la funzione del filesystem. Ma se il comando non riesce per un motivo che non ho previsto, come posso rilevare l'errore per mostrare all'utente un messaggio più utile?

Si tratta di una semplificazione del codice che crea il collegamento simbolico:

$filename = 'some-file.ext'; 
$source_path = '/full/path/to/source/dir/'; 
$dest_path = '/full/path/to/destination/dir/'; 

if(file_exists($source_path . $filename)) { 
    if(is_dir($dest_path)) { 
     if(! file_exists($dest_path . $filename)) { 
      if (symlink($source_path . $filename, $dest_path . $filename)) { 
       echo 'Success'; 
      } else { 
       echo 'Error'; 
      } 
     } 
     else { 
      if (is_link($dest_path . $filename)) { 
       $current_source_path = readlink($dest_path . $filename); 
       if ($current_source_path == $source_path . $filename) { 
        echo 'Link exists'; 
       } else { 
        echo "Link exists but points to: {$current_source_path}"; 
       } 
      } else { 
       echo "{$source_path}{$filename} exists but it is not a link"; 
      } 
     } 
    } else { 
     echo "{$source_path} is not a dir or doesn't exist"; 
    } 
} else { 
    echo "{$source_path}{$filename} doesn't exist"; 
} 

Followup/Soluzioni

Come sugested da Sander, utilizzando set_error_handler() per trasformare gli errori e gli avvisi in eccezioni.

function exception_error_handler($errno, $errstr, $errfile, $errline) { 
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline); 
} 

set_error_handler("exception_error_handler"); 

try { 
    symlink($source_path . $filename, $dest_path . $filename); 
    echo 'Success'; 
} 
catch (ErrorException $ex) { 
    echo "There was an error linking {$source_path}{$filename} to {$dest_path}{$filename}: {$ex->getMessage()}"; 
} 

restore_error_handler(); 

Utilizzando l'operatore @ è un'altra soluzione (although some suggest avoiding it whenever possible):

if (@symlink($source_path . $filename, $dest_path . $filename)) { 
    echo 'Success'; 
} else { 
    $symlink_error = error_get_last();   
    echo "There was an error linking {$source_path}{$filename} to {$dest_path}{$filename}: {$symlink_error['message']}"; 
} 

risposta

4

Penso che si desidera a voler impostare un ErrorHandler che getta eccezioni:

function exception_error_handler($errno, $errstr, $errfile, $errline) { 
    // see http://php.net/manual/en/class.errorexception.php 
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline); 
} 

set_error_handler("exception_error_handler"); 

Allora il vostro codice sarebbe be:

try { 
    symlink(); // when an error occured, it jumps to the catch 
} catch (ErrorException $ex) { 
    // do stuff with $ex 
} 
+0

Questo verrà richiamato per ogni errore? Cosa succede se volessi usare solo su determinate funzioni? – Lando

+0

La cattura verrà richiamata solo al primo errore verificatosi. Puoi leggere l'argomento su http://php.net/manual/en/language.exceptions.php – sroes

+0

Quello che intendevo era come avrei potuto indirizzare questo a una funzione specifica, in seguito ho trovato 'restore_error_handler()' [qui ] (http://stackoverflow.com/a/1241751/1132838) :). – Lando

1

Ti suggerisco di utilizzare il componente Fileysystem che è una soluzione ampiamente utilizzata e testata per le operazioni del file system https://github.com/symfony/Filesystem/blob/master/Filesystem.php#L248

+0

Attualmente non utilizzo alcun framework poiché si tratta di un semplice script. Mi dà alcune idee su come risolvere il problema, grazie per il link. – Lando

+0

Puoi usarlo come componente indipendente senza usare un framework – Ziumin

Problemi correlati