PHP unlink()处理异常

pra*_*tri 25 php exception-handling unlink

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

我试过类似的东西

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

但它没有用.我不是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
}
Run Code Online (Sandbox Code Playgroud)

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

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

goF*_*ard 25

如果您只想克服错误,可以这样做:

@unlink('your_file_name');
Run Code Online (Sandbox Code Playgroud)

一般来说,在php中,@会压制任何错误.

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

if(file_exists('your_file_name')){
    unlink('your_file_name');
}else{
    echo 'file not found';
}
Run Code Online (Sandbox Code Playgroud)

祝好运 :)

  • 问题是存在竞争条件,当调用`file_exists`时文件可能存在,但是另一个进程在调用`unlink`函数之前删除该文件.所以使用`@`可能是最好的选择. (3认同)
  • 是的,除了暗示`@`是一个坏主意.你宁愿正确编码而不是隐藏错误. (2认同)

pro*_*son 21

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

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

你能更具描述性吗? @

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

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

  • 对于高流量站点,`if(file_exists($ path))unlink($ path);`仍然会抛出错误,因为另一个进程已经删除了check/unlink之间的文件. (10认同)
  • 您仍然可以使用`@`,但之后需要检查错误和`FALSE`返回值。 (2认同)

Tar*_*nes 13

这种方法可能看起来很奇怪,但我相信它是最简单的方法

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
}
Run Code Online (Sandbox Code Playgroud)

为什么?

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

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

if(is_file($file) && unlink($file)){
Run Code Online (Sandbox Code Playgroud)

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

但这是最好的方法.

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

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

取消链接

TRUE成功或FALSE失败时的退货.

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

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

编辑:更新的链接网址

  • 不需要使用两次“is_file”。更简单:`if (is_file($file) { if (@unlink($file)) { ...成功... } else { ...取消链接失败...} } else { ...文件没有'不存在...}` (2认同)
  • @ToolmakerSteve通常,你是对的,但在这种情况下,我认为额外的检查是必要的,因为这个答案和其他答案中提到了竞争条件。如果 unlink() 失败,可能是因为该文件在第一次检查时确实存在,但在调用 unlink() 之前的短窗口中被删除了。因此,有必要再次调用 is_file() 来询问即使 unlink() 失败后该文件是否仍然存在,这可以让我们知道该文件是否不存在或者是否存在需要引起更多关注的错误。 (2认同)

skr*_*led 5

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

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

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

  unlink($file);
}
catch(Exception $e) { /* do what you want */ }
Run Code Online (Sandbox Code Playgroud)


VCo*_*rea 5

我的经验表明,在调用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;
}
Run Code Online (Sandbox Code Playgroud)

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

  • 不,@对我不起作用。它适用于其余功能,但不适用于**取消链接**。上次我检查它对我不起作用时,我正在 Apache 2.4 Windows 上使用 PHP 5.4。如前所述,我尝试了很多东西(使用 @ 是我的第一个选择),并且提到的函数是它的唯一工作方式。在每台经过测试的服务器上。 (2认同)