40

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

我尝试了类似的东西

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

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

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

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

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

可以通过错误报告(PHP)(生产和开发环境)操作来隐藏错误吗?

4

8 回答 8

42

注意:这可能不再起作用。见布赖恩的评论

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

@unlink('your_file_name');

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

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

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

祝你好运 :)

于 2013-03-10T02:30:25.367 回答
27

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

不要用 来压制错误@,它很少被推荐。

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

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

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

于 2013-03-10T02:32:21.953 回答
22

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

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
}

为什么?

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

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

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

但这不是一个万无一失的方法,因为在is_file检查和unlink之间的小窗口中删除文件是很常见的。当缓存方法使用文件系统时,我已经经历过几次。

但这是最好的方法。

因此,您可以正确执行所有操作,但仍然会出错!

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

取消链接

TRUE成功或FALSE失败返回。

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

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

编辑:更新的链接 URL

于 2015-11-25T09:59:02.300 回答
6

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

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 */ }
于 2016-04-22T23:05:08.427 回答
4

我的经验表明,在调用unlink()之前调用file_exists()不起作用,即使在调用file_exists ()之前调用了clearstatcache()也是如此。 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;
}

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

于 2018-07-31T15:21:43.323 回答
2

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

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

因此,在尝试了许多方法(如:is_resource()、、is_writable()...stream_get_meta_data()等)之后,我找到了处理错误的唯一最佳方法,同时“删除”一个不存在存在但被某些应用程序使用的文件

function delete_file($pFilename)
{
    if ( file_exists($pFilename) ) { 
        //  Added by muhammad.begawala@gmail.com
        //  '@' 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;
}

=== 用法 ===

try {
    if( delete_file('hello_world.xlsx') === true )
        echo 'File Deleted';
}
catch (Exception $e) {
    echo $e->getMessage(); // will print Exception message defined above.
}
于 2018-09-29T17:23:15.397 回答
1

使用 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;
    }
于 2016-10-15T15:35:47.800 回答
0
if (file_exists($file) && is_writable($file)) {
    return  unlink($file);
}
于 2021-10-31T10:03:50.793 回答