2

PHP 中的许多函数提供与其同名的 libc 相同的功能,返回 FALSE 表示失败。

有没有办法获得有关实际错误的更多详细信息?在 C 中,我会编写如下代码:

if (unlink(path)) {
        switch(errno) {
        case ENOENT: .....
        case ENAMETOOLONG: ...
        ....
        default: warn(path);
        }
}

PHP方式是什么?

4

5 回答 5

3

libc中没有errnoas。一些库提供类似的功能(如 ie mysql_errno()curl_errno())。如果您使用的是 PHP5,您可以尝试使用error_get_last()

于 2013-06-03T19:35:52.857 回答
0

这完全取决于您正在使用的库。不同的库有不同的方法来检索错误,通常使用函数。例如在(过时的)MySQL 库中,您使用mysql_error()返回最后发生的错误的具体错误消息。

于 2013-06-03T19:33:55.893 回答
0

我不确定它是否可能,但你可以试试这个功能

error_get_last()

它将返回发生的最后一个错误。

可悲的是,这个库没有更多的“内置”选项,所以你最好做如下检查:

if (file_exists($file)) // check if the file exists

if (is_writable($file)) // check if php can write to the file

所以你可以知道它为什么会失败。

于 2013-06-03T19:38:46.907 回答
-2

errno是预定义常量错误http://php.net/manual/en/errorfunc.constants.php如果你想处理错误,你可以使用ob_start而不是set_error_handler

<?php
error_reporting(E_ALL);

ob_start('error_handler');

function error_handler($output) {
  $errno = array(
    "1" => "E_ERROR",
    "2" => "E_WARNING",
    "4" => "E_PARSE",
    "8" => "E_NOTICE",
    "16" => "E_CORE_ERROR",
    "32" => "E_CORE_WARNING",
    "64" => "E_COMPILE_ERROR",
    "128" => "E_COMPILE_WARNING",
    "256" => "E_USER_ERROR",
    "512" => "E_USER_WARNING",
    "1024" => "E_USER_NOTICE",
    "2048" => "E_STRICT",
    "4096" => "E_RECOVERABLE_ERROR",
    "8192" => "E_DEPRECATED",
    "16384" => "E_USER_DEPRECATED",
    "32767" => "E_ALL"
  );
  if(error_get_last())
  {
    $error = error_get_last();
    $output = "";
    foreach($error as $info => $string) {
      if ($info == "type")
        $output.= "{$info}: {$string} - {$errno[$string]}\n";
      else
        $output.= "{$info}: {$string}\n";
    }
  }
  return $output;
}

undefinedFunc();

/*
* type: 1 - E_ERROR
* message: Call to undefined function undefinedFunc()
* line: 29
*/

?>
于 2016-02-23T19:24:02.980 回答
-4

没有errno。它不是必需的,因为无论如何您都无法在 PHP 中正确处理错误。

请注意,error_get_last()(需要 PHP 5.2 或更高版本)不能替代类似的东西,errno因为error_get_last()是一场安全噩梦。如果您曾经输出过这些信息的一部分,它就会向公众公开 PHP 的内部结构。从安全的角度来看,任何此类泄露的信息都是重大安全事件,应报告给组织的 CERT 以立即缓解。

例子:

fsockopen("unix://sock")

可能发生的错误有很大的不同,所以也许您想通知您的用户几种可能的状态,以便他们知道该打电话给谁来修复错误。不要那样做。甚至不要考虑这样做!

没有办法轻易判断发生了哪个错误,因为这些信息被深深地埋藏在error_get_last()里面,在任何情况下都几乎没有办法正确处理它:

示例输出(JSON):

{"type":2
,"message":"fsockopen(): unable to connect to unix://sock:-1 (Connection refused)"
,"file":"/var/www/html/test.php"
,"line":3
}

这意味着,应用程序可能没有运行,您应该联系应用程序支持。然而

{"type":2
,"message":"fsockopen(): unable to connect to unix://sock:-1 (No such file or directory)"
,"file":"/var/www/html/test.php"
,"line":3
}

可能意味着,有些东西没有正确部署,所以你可能必须联系开发人员来修复部署。但随着

{"type":2
,"message":"fsockopen(): unable to connect to unix://sock:-1 (Permission denied)"
,"file":"/var/www/html/test.php"
,"line":3
}

您有一些配置问题的迹象,这可能必须由 Web 服务的操作员修复。

但不要落入陷阱并相信这个函数的输出,因为可能有这样的东西:

{"type":2
,"message":"fsockopen(): unable to connect to unix://sock:-1 (basic shuttle outflop)\n:-1 (No such file or directory)",
,"file":"/var/www/html/test.php"
,"line":3
}

例如,这可能源于一些正在进行的黑客攻击,其中有人成功地替换了要读取的套接字名称,"sock:-1 (basic shuttle outflop)\n"从而向黑客展示了他成功注入了一些代码。

读:

暴露message,即使只是部分暴露,是一件非常糟糕的事情。正确处理这个问题的门槛是无限的,所以它不能用来决定做什么,否则你的应用程序可能会将敏感的内部信息泄露给一些攻击方。

TL;博士

使用 PHP 没有办法以不同的方式正确处理不同的错误情况。时期。

  • 使用 PHP 时只有 2 个状态:OK 和 ERR(不是 100% OK)
  • 无论错误的类型如何,始终以相同的方式处理所有错误:
  • 出现任何错误,让 PHP 应用程序die()立即执行。其他一切都会像地狱一样不安全。
  • 与其事后处理错误,不如在可能的错误到达 PHP 代码之前解决它们,因此在正常的程序流程中永远不会发生错误。

然后你永远不需要类似的东西errno,导致 PHP 代码在典型的错误情况下可能会做一些合理的事情:

  • 如果任何(实习生或外部)错误命中 PHP 代码,代码将终止并发出致命通知。好像忘记了某些错误条件,这意味着代码有错误。

  • 所有其他错误条件都在它们发生之前得到处理,因此您始终拥有一个独立于错误的程序流,因为没有错误可以影响该代码。

另请注意,E_WARNING 也必须作为错误处理。否则,您将面临使用 PHP 的不安全风险,因为许多与安全相关的问题只是作为警告出现。

当然,您可以尝试忽略这一切。但这意味着你的生活很危险。如果此代码作为服务发布或可公开访问,则会危及他人。

于 2019-03-05T17:54:29.623 回答