如何在PHP中访问errno?

时间:2013-06-03 19:32:25

标签: php

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

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

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

什么是PHP方式?谢谢!

5 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

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
*/

?>

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

error_get_last()

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

可悲的是,此lib没有更多“内置”选项,因此您最好进行以下检查:

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

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

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

答案 4 :(得分:-1)

没有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; DR

  

使用PHP不能正确处理不同的错误情况。期间。

  • 对于PHP,只有两种状态:OK和ERR(不是100%OK的任何状态)
  • 无论错误的类型如何,始终以相同的方式处理所有错误:
  • 遇到任何错误,请立即让PHP应用程序die()。其他一切都会变得不安全。
  • 以后不要处理错误,而要先解决可能的错误,然后再打击PHP代码,这样,正常程序流中就永远不会发生错误。

然后,您再也不需要像errno这样的东西,从而导致PHP代码在典型的错误情况下可能会做一些合理的事情:

  • 如果任何(实习生或外部实习生)错误出现在PHP代码中,则该代码将以致命提示终止。仿佛忘记了某些错误情况,这意味着代码中有错误。

  • 所有其他错误情况在发生之前都会得到处理,因此您始终拥有独立于错误的程序流,因为没有错误可以击中该代码。

  

还请注意,E_WARNING也必须视为错误。否则,PHP可能会带来安全隐患,因为许多与安全相关的问题都只是作为警告出现。

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