我包含这个简单的错误处理函数来格式化错误:
date_default_timezone_set('America/New_York');
// Create the error handler.
function my_error_handler ($e_number, $e_message, $e_file, $e_line, $e_vars) {
// Build the error message.
$message = "An error occurred in script '$e_file' on line $e_line: \n<br />$e_message\n<br />";
// Add the date and time.
$message .= "Date/Time: " . date('n-j-Y H:i:s') . "\n<br />";
// Append $e_vars to the $message.
$message .= "<pre>" . print_r ($e_vars, 1) . "</pre>\n<br />";
echo '<div id="Error">' . $message . '</div><br />';
} // End of my_error_handler() definition.
// Use my error handler.
set_error_handler ('my_error_handler');
当我将其包含在带有以下
的脚本中时$dom = new DOMDocument();
$dom->loadHTML($output);
$xpath = new DOMXPath($dom);
并解析一个网页(在这种情况下,http://www.ssense.com/women/designers/all/all/page_1,我有权解析)我收到错误,如
AN ERROR OCCURRED IN SCRIPT '/HSPHERE/LOCAL/HOME/SITE.COM/SCRIPT.PHP' ON LINE 59:
DOMDOCUMENT::LOADHTML(): HTMLPARSEENTITYREF: NO NAME IN ENTITY, LINE: 57
和
AN ERROR OCCURRED IN SCRIPT '/HSPHERE/LOCAL/HOME/SITE.COM/SCRIPT.PHP' ON LINE 59:
DOMDOCUMENT::LOADHTML(): TAG NAV INVALID IN ENTITY, LINE: 58
有许多错误,页面永远不会完成加载。但是,如果我不包含此错误处理程序,则行
$dom->loadHTML($output);
不会抛出任何错误,我会在几秒钟内得到我期望的结果。我假设错误处理程序正在捕获与loadHTML()相关的警告,这些警告未以其他方式报告。 (即使我使用
@$dom->loadHTML($output);
它仍会报告错误。)我如何修改错误处理程序以适应对loadHTML()的调用,或以其他方式解决此问题?
答案 0 :(得分:3)
您要加载的网页包含许多错误。例如,&
而不是HTML中的&
实体。
PHP DOM使用libxml,因此要禁用插入行的所有错误:
libxml_use_internal_errors(true);
稍后您可以使用libxml_get_errors()获取解析错误列表。
答案 1 :(得分:2)
导致错误的不是自定义错误处理程序。
我在没有自定义错误处理程序的情况下运行了以下代码:
$output = file_get_contents("http://www.ssense.com/women/designers/all/all/page_1");
$dom = new DOMDocument();
$dom->loadHTML($output);
$xpath = new DOMXPath($dom);
当我运行它时,我收到了大量类似于错误处理程序中的警告消息。
我认为您遇到的问题只是您的错误处理程序报告了PHP默认情况下未报告的错误。
默认情况下,错误报告级别由您的php.ini
设置决定,但可以使用error_reporting()
功能覆盖。设置自己的错误处理程序时,必须自己确定要处理的报告级别。您的错误处理程序将在每个错误和通知上调用,因此您将输出所有的错误消息,除非您明确检查针对当前{{1}生成的错误等级。
请记住,使用error_reporting()
错误抑制运算符只是为该行设置@
的简写。例如,这一行:
error_reporting(0)
简单地说明以下内容:
@$dom->loadHTML($output);
由于在使用自定义处理程序时完全绕过了正常的PHP错误报告,因此使用$errorLevel = error_reporting(0);
$dom->loadHTML($output);
error_reporting($errorLevel);
运算符是没有意义的,因为完全忽略了当前的@
级别。您必须将自定义代码写入错误处理程序以检查当前error_reporting()
级别并相应地处理它,例如:
error_reporting()
我的假设是,当不使用自定义错误处理程序时,PHP只是默认为function my_error_handler() {
if (error_reporting() == 0) {
return; // do nothing when error_reporting is disabled.
}
// normal error handling here
}
级别,该级别低于生成的错误。
如果您将error_reporting()
添加到代码顶部,即使您没有启用自定义错误处理程序,也会看到相同的错误。