2012-11-13 15 views
5

Podczas korzystania filesystem functions, jaki byłby poprawny sposób obsługi błędów, takich jak:Jaki jest poprawny sposób obsługi błędów i ostrzeżeń na temat funkcji systemu plików w PHP?

Ostrzeżenie: dowiązanie symboliczne(): Nie ma takiego pliku lub katalogu w /path-to-script/symlink.php na linii XXX

Moje zwykłe podejście polega na sprawdzeniu, czy nie wystąpił warunek, który mógł spowodować błąd przed wywołaniem funkcji systemu plików. Ale jeśli polecenie nie powiedzie się z powodu, którego nie przewidziałem, jak mogę złapać błąd, aby pokazać użytkownikowi bardziej przydatny komunikat?

Jest to uproszczenie kodu, który tworzy symboliczny link:

$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"; 
} 

obserwacji/Rozwiązania

Jak sugested przez Sander, używając set_error_handler() włączyć błędów i ostrzeżeń do wyjątków.

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(); 

Korzystanie z operatorem @ jest kolejnym rozwiązaniem (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']}"; 
} 

Odpowiedz

4

myślę chcesz chcesz ustawić ErrorHandler która generuje wyjątki:

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"); 

Wtedy twój kod będzie być:

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

Zostanie to wywołane z powodu każdego błędu? Co, jeśli chciałem skorzystać, to tylko w przypadku niektórych funkcji? – Lando

+0

Połów zostanie wywołany tylko przy pierwszym błędzie, który wystąpił. Możesz przeczytać na ten temat na http://php.net/manual/en/language.exceptions.php – sroes

+0

Co miałem na myśli, to w jaki sposób mógłbym skierować to do określonej funkcji, później znalazłem 'restore_error_handler()' [tutaj ] (http://stackoverflow.com/a/1241751/1132838) :). – Lando

1

Proponuję użyć komponentu Fileysystem, który jest szeroko stosowanym i przetestowanym rozwiązaniem dla operacji w systemie plików. https://github.com/symfony/Filesystem/blob/master/Filesystem.php#L248

+0

Obecnie nie używam żadnej struktury, ponieważ jest to prosty skrypt. Daje mi kilka pomysłów, jak rozwiązać problem, dzięki za link. – Lando

+0

Można go używać jako samodzielnego komponentu bez korzystania z frameworka – Ziumin

Powiązane problemy