我包含了这个简单的错误处理函数来格式化错误:
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()的调用,或者以其他方式修复此问题?
您正在加载的网页包含许多错误。例如,&
而不是HTML中的&
实体。
PHP DOM使用libxml,因此要禁用所有错误,请插入以下行:
libxml_use_internal_errors(true);
稍后可以使用libxml_get_errors()获得解析错误列表。
导致错误的不是自定义错误处理程序。
我运行了以下代码,没有自定义错误处理程序:
$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()
函数来覆盖。当您设置自己的错误处理程序时,您必须自己确定要处理的报告级别。您的错误处理程序将在上调用每个错误和通知,因此您将为输出所有的错误消息,除非您显式检查针对当前error_reporting()
级别生成的错误。
请记住,使用@
错误抑制操作符只是为该行设置error_reporting(0)
的简写。例如,这一行:
@$dom->loadHTML($output);
是以下内容的简写:
$errorLevel = error_reporting(0);
$dom->loadHTML($output);
error_reporting($errorLevel);
由于使用自定义处理程序时完全绕过了正常的PHP错误报告,因此使用@
操作符是没有意义的,因为当前的error_reporting()
级别被完全忽略。您必须在错误处理程序中编写自定义代码来检查当前的error_reporting()
级别并相应地处理它,例如:
function my_error_handler() {
if (error_reporting() == 0) {
return; // do nothing when error_reporting is disabled.
}
// normal error handling here
}
我的假设是,当不使用自定义错误处理程序时,PHP只是默认使用error_reporting()
级别,该级别低于所产生的错误。
如果您将error_reporting(E_ALL | E_STRICT);
添加到代码的顶部,即使您没有启用自定义错误处理程序,您也会看到相同的错误。