【问题标题】:What is the correct way of handling errors and warnings on filesystem functions in PHP?在 PHP 中处理文件系统函数的错误和警告的正确方法是什么?
【发布时间】:2012-11-02 05:07:29
【问题描述】:

当使用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']}";
}

【问题讨论】:

    标签: php exception-handling error-handling


    【解决方案1】:

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

    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
    }
    

    【讨论】:

    • 每个错误都会调用这个?如果我只想在某些功能上使用呢?
    • 只会在发生的第一个错误时调用 catch。您可以在php.net/manual/en/language.exceptions.php 阅读有关该主题的内容
    • 我的意思是如何将其定位到特定功能,后来我发现restore_error_handler() here :)。
    【解决方案2】:

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

    【讨论】:

    • 我目前没有使用任何框架,因为这是一个简单的脚本。它确实给了我一些关于如何解决问题的想法,谢谢你的链接。
    • 您可以将其用作独立组件而无需使用框架
    猜你喜欢
    • 1970-01-01
    • 2020-12-02
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    • 2017-10-24
    • 2011-11-29
    • 2017-09-20
    • 1970-01-01
    相关资源
    最近更新 更多