当 php 的 mkdir 失败时,如何找到原因?

How to find a reason when mkdir fails from PHP?

提问人:Milan Babuškov 提问时间:5/30/2009 最后编辑:Milan Babuškov 更新时间:3/25/2013 访问量:43521

问:

PHP 的 mkdir 函数只返回 true 和 false。问题是当它返回 false 时。

如果我在启用错误报告的情况下运行,我会在屏幕上看到错误消息。我还可以在 Apache 日志中看到错误消息。但是我想抓取消息的文本并对其进行其他操作(例如,通过IM发送给自己)。如何获取错误文本?

更新:按照艾曼的想法,我得出了这个结论:

function error_handler($errno, $errstr) {
    global $last_error;
    $last_error = $errstr;
}

set_error_handler('error_handler');
if (!mkdir('/somedir'))
    echo "MKDIR failed, reason: $last_error\n";
restore_error_handler();

但是,我不喜欢它,因为它使用全局变量。对更清洁的解决方案有什么想法吗?

php 错误报告 mkdir

评论

0赞 Robert K 5/30/2009
Soulmerge 的答案是更好的选择,因为它会在不替换处理程序的情况下告诉您错误。
4赞 soulmerge 5/30/2009
请注意,错误处理程序存储在 PHP 的堆栈上,这意味着对 restore_error_handler() 的调用将恢复以前的错误处理程序,无论是内置处理程序还是其他自定义处理程序。因此,暂时用 set_error_handler() 替换错误处理程序不会有任何损失。

答:

75赞 soulmerge 5/30/2009 #1

您可以禁止显示警告并使用 error_get_last()

if (!@mkdir($dir)) {
    $error = error_get_last();
    echo $error['message'];
}

评论

9赞 Frank Farmer 1/8/2010
+1,但值得注意的是,如果 mkdir() 和 error_get_last() 之间发生另一个错误,这可能是脆弱的,当你的代码变得更复杂时,这很可能发生(作为一个极端的、不切实际的例子,tick 函数可能会在 error_get_last() 调用之前运行并生成错误)。每当您使用任何类型的 get-last-error 函数时,这始终是一种风险。
2赞 DomQ 4/7/2022
@FrankFarmer你是对的,但不幸的是,PHP并没有给我们比这更好的选择。
21赞 Alistair Evans 5/30/2009 #2

您可以使用例外情况:

设置一些代码,如下所示:

function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");

然后做:

try {
   mkdir('/somedir');
} catch(ErrorException $ex) {
   echo "Error: " . $ex->getMessage();
}

这应该做你想做的事。

如果你想保留 php 错误处理程序,那么在尝试 catch 块之后,只需调用:

restore_error_handler()

评论

1赞 Daniel Wedlund 5/30/2009
+1 我喜欢这种方法,我没有测试过,但感觉很扎实。此外,它看起来对 oo 更友好;)
2赞 nick fox 3/25/2013
此外,PHP 的 OO 库可以更好地处理所有这些东西 php.net/manual/en/class.splfileobject.php
2赞 Alistair Evans 3/25/2013
@nickfox mkdir 不会引发异常,这就是自定义错误处理程序引发异常的原因。至于PHP的OO库,是的,他们可能做得更好。
0赞 Justin 5/15/2019
这是正确的答案,因为这也具有在堆栈跟踪中显示正确行号的好处。
4赞 nick fox 3/25/2013 #3

我使用如下内容:

if(! @mkdir('$fileLocation', 0777, $recursive = true)){
    $mkdirErrorArray = error_get_last();
    throw new Exception('cant create directory ' .$mkdirErrorArray['message'], 1);
}