PHP unlink() 处理异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15318230/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 09:02:29  来源:igfitidea点击:

PHP unlink() handling the exception

phpexception-handlingunlink

提问by prakashchhetri

Well, I have been wondering if I can handle the unlink()function properly. I dont want the unlink()function to throw some nasty error if it is unable to unlink the file (may be due to the File not found).

好吧,我一直想知道我是否可以unlink()正确处理该功能。unlink()如果无法取消链接文件(可能是由于找不到文件),我不希望该函数抛出一些令人讨厌的错误。

I tried something like

我试过类似的东西

try { 
    unlink("secret/secret.txt"); 
} catch(Exception $e) { 
    print "whoops!"; 
    //or even leaving it empty so nothing is displayed
} 

But it is not working. I am no expert in PHP. I searched and found this exception handling code somewhere in the web. But as I can remember my school days, the same was used for Java. SO it should have worked. I dont know whats wrong with the code.

但它不起作用。我不是 PHP 专家。我在网上某处搜索并找到了这个异常处理代码。但我记得我的学生时代,Java 也是如此。所以它应该有效。我不知道代码有什么问题。

Or can I simply use a if..else statement like

或者我可以简单地使用 if..else 语句,如

if(unlink($file)){
  //leaving here empty must ensure that nothing is displayed
}else{
  //leaving here empty must ensure that nothing is displayed
}

But this code isnt working either. Where am I doing the mistake? What are the other ways to handle it properly?

但是这段代码也不起作用。我在哪里做错了?有什么其他方法可以正确处理它?

Can the errors be hidden by manipulating with the error reporting (PHP) (Production and Development environment) ??

是否可以通过使用错误报告(PHP)(生产和开发环境)进行操作来隐藏错误??

采纳答案by prodigitalson

unlinkdoesn't throw exceptions, in generates errors. The proper way to do this is check that the file exists before trying to call unlinkon it. If you are merely worried about not having the errors output then you should just turn off display_errorswhich you should always do in a production environment anyway. Then they will just be logged.

unlink不会抛出异常,会产生错误。执行此操作的正确方法是在尝试调用文件之前检查该文件是否存在unlink。如果您只是担心没有错误输出,那么您应该关闭display_errors您应该始终在生产环境中执行的操作。然后他们将被记录。

Do not suppress errors with the @, its rarely advisable.

不要用 抑制错误@,它很少是可取的。

Can you be more descriptive about @

你能更详细地描述一下吗 @

Im not sure what you mean exactly. But the documentation is here. As far as why you don't want to use it... That is because then you never know that code isn't working or is problematic. Even if the code still works from a functional perspective it's still got an issue and that issue could potentially make something else completely not work at some point. If you never have the error you'll probably waste a lot of time debugging.

我不确定你的意思是什么。但是文档在这里。至于为什么你不想使用它......那是因为你永远不知道代码不起作用或有问题。即使从功能的角度来看代码仍然有效,它仍然存在问题,并且该问题可能会使其他某些东西在某些时候完全无法工作。如果您从未遇到过错误,您可能会浪费大量时间进行调试。

Its fine to change your log level or disable the display of errors, but you never want to completely suppress them.

更改日志级别或禁用错误显示很好,但您永远不想完全抑制它们。

回答by goFrendiAsgard

If you want to only surpress the error, you can do this:

如果你只想抑制错误,你可以这样做:

@unlink('your_file_name');

Generally, in php, @ will surpress any error.

通常,在 php 中,@ 会抑制任何错误。

The better way is minimize the error probability. You've say that one of error possibility is caused by non-exist file. If I were you, I'll do this:

更好的方法是最小化错误概率。您已经说过错误可能性之一是由不存在的文件引起的。如果我是你,我会这样做:

if(file_exists('your_file_name')){
    unlink('your_file_name');
}else{
    echo 'file not found';
}

Good luck :)

祝你好运 :)

回答by TarranJones

This method may seem strange but I believe it is the most foolproof one, it accounts for "race conditions".

这种方法可能看起来很奇怪,但我相信它是最万无一失的方法,它说明了“竞争条件”。

is_file

is_file

if(is_file($file) && @unlink($file)){
    // delete success
} else if (is_file ($file)) {
    // unlink failed.
    // you would have got an error if it wasn't suppressed
} else {
  // file doesn't exist
}

Why?

为什么?

Firstly is_fileis the correct method to check if a FILE exists not file_exists. file_existschecks for both directories and files so may return the TRUEfor a directory with the same filename, you cannot remove a directory with unlinkand doing so will throw an error.

首先is_file是检查 FILE 是否存在而不是file_exists的正确方法。 file_exists检查目录和文件,因此可能会返回TRUE具有相同文件名的目录,您不能使用unlink删除目录,这样做会引发错误。

Checking a file exists(is_file) before you unlinkis the correct/best way to delete a file.

取消链接之前检查文件是否存在(is_file)是删除文件的正确/最佳方法。

if(is_file($file) && unlink($file)){

But it is not a foolproof method as it is common for a file to be deleted in the small window between the is_filecheck and the unlink. I have experianced this several times when a caching method uses the filesystem.

但这不是万无一失的方法,因为在is_filecheck 和unlink之间的小窗口中删除文件是很常见的。当缓存方法使用文件系统时,我已经多次体验过这种情况。

But it is best method available.

但这是最好的方法。

So you can do everything right and still get an error!

所以你可以做正确的一切,但仍然会出错!

Well at least the error tells you if it fails....well actually you can tell if it fails without the error

好吧,至少错误会告诉你它是否失败......实际上你可以在没有错误的情况下判断它是否失败

unlink

取消链接

Returns TRUEon success or FALSEon failure.

TRUE成功或FALSE失败时返回。

If you have coded it correctly and can differentiate between a success and failed unlinkthen YES suppress the error, it does not benifit you or your code.

如果您对它进行了正确编码并且可以区分成功和失败的取消链接,那么YES 会抑制错误,它不会使您或您的代码受益。

Whether the error is suppressed or not, This is the best method i can think of to prevent it from happening. By reducing the time between the check and the delete you will reduce the likeliness of it throwing an error.

无论错误是否被抑制,这是我能想到的防止它发生的最好方法。通过减少检查和删除之间的时间,您将减少抛出错误的可能性。

EDIT: updated link URLs

编辑:更新的链接 URL

回答by skrilled

You can use is_writableto test whether you have proper permissions to modify or delete a file.

您可以使用is_writable来测试您是否具有修改或删除文件的适当权限。

http://php.net/manual/en/function.is-writable.php

http://php.net/manual/en/function.is-writable.php

try {
  if(!is_writable($file))
      throw new Exception('File not writable');

  unlink($file);
}
catch(Exception $e) { /* do what you want */ }

回答by VCorrea

My experience says that calling file_exists()just before calling unlink()does NOTwork, even if clearstatcache()was called just before calling file_exists().

There are many combinations of PHP versions and operating systems and the only way that I have found that always works (that is, avoids showing the warning message in case of error) is making my own function silent_unlink():

我的经验说,调用file_exists()只调用之前的unlink()确实工作,即使clearstatcache()函数被调用只调用之前file_exists()

PHP 版本和操作系统有多种组合,我发现始终有效的唯一方法(即避免在出现错误时显示警告消息)是创建我自己的函数Silent_unlink()

function silent_unlink( $filename )
{
  $old_er = error_reporting();
  error_reporting( $old_er & ~E_WARNING );
  $result = unlink( $filename );
  error_reporting( $old_er );
  return $result;
}

It disables the error reporting of warnings just for calling unlink()and restores the previous error_reporting()status.

它禁用仅用于调用unlink()的警告错误报告并恢复先前的error_reporting()状态。

回答by Muhammad

Handling "Resource Unavailable" error by unlink() as Exception using try catch

使用 try catch 通过 unlink() 作为异常处理“资源不可用”错误

Even is_file()or file_exists()will check for file is exists or not, there are chances that file is being used by some applications that will prevent deletion and unlink()will display "Resource Unavailable" error.

即使is_file()file_exists()将检查文件是否存在,也有可能文件正在被某些应用程序使用,这将阻止删除并unlink()显示“资源不可用”错误

So after trying many methods like: is_resource(), is_writable(), stream_get_meta_data()...etc, I reached the only best way to handle error while "deleting"a file that is either not existsor is exists but being used by some application

喜欢尝试很多方法后这样:is_resource()is_writable()stream_get_meta_data()...等等,我伸手处理错误的唯一最佳途径,而“删除”的文件或者是不存在的或者是存在,但正在使用的某些应用

function delete_file($pFilename)
{
    if ( file_exists($pFilename) ) { 
        //  Added by [email protected]
        //  '@' will stop displaying "Resource Unavailable" error because of file is open some where.
        //  'unlink($pFilename) !== true' will check if file is deleted successfully.
        //  Throwing exception so that we can handle error easily instead of displaying to users.
        if( @unlink($pFilename) !== true )
            throw new Exception('Could not delete file: ' . $pFilename . ' Please close all applications that are using it.');
    }   
    return true;
}

=== USAGE ===

=== 用法 ===

try {
    if( delete_file('hello_world.xlsx') === true )
        echo 'File Deleted';
}
catch (Exception $e) {
    echo $e->getMessage(); // will print Exception message defined above.
}

回答by Dziamid Harbatsevich

Wrote this for few files or empty folders deletions as it happens time-to-time. For more scale it is better to use recursive functions.

为少数文件或空文件夹删除而写,因为它不时发生。对于更大的规模,最好使用递归函数。

/*
*   Delete specific files and empty folders.
*   IN: $arr_path_del (array with file/folder paths to delete); return: true/false;
 */
function delSpecFiles($arr_path_del)
{
    $result = [];
    foreach ($arr_path_del as $value)
    {
        $value = $_SERVER['DOCUMENT_ROOT'].$value;
        if (file_exists($value))
        {
            if(!is_dir($value) && !unlink($value))                                                                  // delete files
            {
                $result += [false];
            }
            if (is_dir($value) && !rmdir($value))                                           // delete empty folders
            {
                $result += [false];
            }
        }
    }
    if (array_search(false, $result))                                                       // check if there were any faults
    {
        return false;
    }
    return true;
} //--/ delSpecFiles()
$arr_path_del = ['/xxtest.php', '/xxtest', '/rgerger.txt'];
delSpecFiles($arr_path_del);

回答by maximark

Use PHP_Exceptionizer https://github.com/DmitryKoterov/php_exceptionizer/blob/master/lib/PHP/Exceptionizer.php

使用 PHP_Exceptionizer https://github.com/DmitryKoterov/php_exceptionizer/blob/master/lib/PHP/Exceptionizer.php

$exceptionizer = new PHP_Exceptionizer(E_ALL);
try {
        unlink($file)
    }  catch (E_WARNING $e) {
        return false;
    }