PHP 中的许多函数提供与其同名的 libc 相同的功能,返回 FALSE 表示失败。
有没有办法获得有关实际错误的更多详细信息?在 C 中,我会编写如下代码:
if (unlink(path)) {
switch(errno) {
case ENOENT: .....
case ENAMETOOLONG: ...
....
default: warn(path);
}
}
PHP方式是什么?
PHP 中的许多函数提供与其同名的 libc 相同的功能,返回 FALSE 表示失败。
有没有办法获得有关实际错误的更多详细信息?在 C 中,我会编写如下代码:
if (unlink(path)) {
switch(errno) {
case ENOENT: .....
case ENAMETOOLONG: ...
....
default: warn(path);
}
}
PHP方式是什么?
libc中没有errnoas。一些库提供类似的功能(如 ie mysql_errno()、curl_errno())。如果您使用的是 PHP5,您可以尝试使用error_get_last()
这完全取决于您正在使用的库。不同的库有不同的方法来检索错误,通常使用函数。例如在(过时的)MySQL 库中,您使用mysql_error()返回最后发生的错误的具体错误消息。
我不确定它是否可能,但你可以试试这个功能
error_get_last()
它将返回发生的最后一个错误。
可悲的是,这个库没有更多的“内置”选项,所以你最好做如下检查:
if (file_exists($file)) // check if the file exists
和
if (is_writable($file)) // check if php can write to the file
所以你可以知道它为什么会失败。
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
*/
?>
没有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 没有办法以不同的方式正确处理不同的错误情况。时期。
die()立即执行。其他一切都会像地狱一样不安全。然后你永远不需要类似的东西errno,导致 PHP 代码在典型的错误情况下可能会做一些合理的事情:
如果任何(实习生或外部)错误命中 PHP 代码,代码将终止并发出致命通知。好像忘记了某些错误条件,这意味着代码有错误。
所有其他错误条件都在它们发生之前得到处理,因此您始终拥有一个独立于错误的程序流,因为没有错误可以影响该代码。
另请注意,E_WARNING 也必须作为错误处理。否则,您将面临使用 PHP 的不安全风险,因为许多与安全相关的问题只是作为警告出现。
当然,您可以尝试忽略这一切。但这意味着你的生活很危险。如果此代码作为服务发布或可公开访问,则会危及他人。