在PHP中处理文件系统函数的错误和警告的正确方法是什么?

时间:2012-11-13 18:17:12

标签: php exception-handling error-handling

使用filesystem functions时,处理错误的正确方法是什么,例如:

  

警告:symlink():第XXX行的/path-to-script/symlink.php中没有此类文件或目录

我通常的方法是在调用文件系统函数之前检查可能产生错误的任何条件。但是如果命令失败的原因我没有预见到,我如何捕获错误以向用户显示更有用的消息?

这是创建符号链接的代码的简化:

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

跟进/解决方案

由Sander吮吸,使用set_error_handler()将错误和警告转换为异常。

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

使用@运算符是另一种解决方案(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']}";
}

2 个答案:

答案 0 :(得分:4)

我想你想要设置一个抛出异常的错误处理程序:

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

然后你的代码将是:

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

答案 1 :(得分:1)

我建议使用广泛使用的Fileysystem组件并测试文件系统操作的解决方案https://github.com/symfony/Filesystem/blob/master/Filesystem.php#L248

相关问题