五月综合缴情婷婷六月,色94色欧美sute亚洲线路二,日韩制服国产精品一区,色噜噜一区二区三区,香港三级午夜理伦三级三

您現(xiàn)在的位置: 365建站網(wǎng) > 365文章 > PHP: 禁止 DomDocument::loadHTML() 對(duì)不規(guī)范的HTML輸出警告信息

PHP: 禁止 DomDocument::loadHTML() 對(duì)不規(guī)范的HTML輸出警告信息

文章來源:365jz.com     點(diǎn)擊數(shù):1767    更新時(shí)間:2018-07-21 09:22   參與評(píng)論

DOM是php比較新的xml和html處理類,可以像javascript那樣方便的操作DOM樹,網(wǎng)上更多的是介紹它處理XML的情況,

很久之前都有注意到這個(gè)問題,沒去處理。但最近服務(wù)器頻繁被攻擊,錯(cuò)誤信息太多,于是想到把這玩意兒干掉。

以前總是使用如下的方式加載HTML:

$doc = new DOMDocument();
$doc->loadHTML('<?xml version="1.0" encoding="UTF-8" ?>' . $html);

但對(duì)于不是特別規(guī)范的HTML文檔,總是有太多的警告信息,太煩:

PHP message: PHP Warning:  DOMDocument::loadHTML(): htmlParseEntityRef: expecting ';' in Entity, line: 3 in index.php on line 33

解決辦法

DomDocument 這個(gè)類是調(diào)用 libxml 來解析HTML的,所以在libxml中設(shè)置臨時(shí)不輸出錯(cuò)誤或警告即可:

// modify state
$libxml_previous_state = libxml_use_internal_errors(true);
// parse
$dom->loadHTML($html);
// handle errors
libxml_clear_errors();
// restore
libxml_use_internal_errors($libxml_previous_state);


另外讀取遠(yuǎn)程文件出現(xiàn)的亂碼問題解決方法:

我要處理的html是使用curl從網(wǎng)頁上讀取過來的,一個(gè)是百度的首頁,gb2312字符集,一個(gè)是有道的首頁,utf8字符集,兩者的html頭部分分別如下:

<html><head><title>百度一下,你就知道   </title><meta http-equiv=Content-Type content="text/html;charset=gb2312">

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="/pack23501M/index.css" type="text/css"/>
<script type="text/javascript" src="/pack23501M/all.js"></script>
<title>有道</title>

可以看出百度的代碼非常不規(guī)范,而有道就好多了,這雖然是題外話,其實(shí)還是有些關(guān)系的,后面會(huì)提到。

以上兩段html代碼,用同樣的方式處理結(jié)果卻不同,比如下面簡(jiǎn)單的處理(輸出網(wǎng)頁的title):

$dom = new DOMDocument();
@$dom->loadHTML($html);
echo $dom->getElementsByTagName('title')->item(0)->nodeValue;
...
$html = $dom->saveHTML();

有道的輸出結(jié)果是正常的,百度卻是亂碼:

????o|??????????? ?°±??¥é??

由于php文檔的loadHTML上說了,DOM內(nèi)部處理全部都是utf8的,所以除了傳入內(nèi)容要utf8化之外,傳入的內(nèi)容中最好還有聲明字符集的html代碼:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

注意,這就是DOM處理html和xml最大的不同了,xml一般要求在第一行就顯示的聲明字符集,而html則靈活得多,可聲明可不聲明。不過不管輸出的內(nèi)容是正常還是亂碼,dom內(nèi)的nodeValue和最終的輸出結(jié)果都是一致的,說明dom工作正常,問題就在輸入數(shù)據(jù)上。

于是,針對(duì)百度的gb2312網(wǎng)頁內(nèi)容,增加了兩項(xiàng)處理,第一項(xiàng)是使用mb_convert_encoding把網(wǎng)頁內(nèi)容由gb2312編碼轉(zhuǎn)換為utf8編碼,第二項(xiàng)是把html中的:

<meta http-equiv=Content-Type content="text/html;charset=gb2312">

替換成了utf8的:

<meta http-equiv="Content-Type" content="text/html;charset=utf-8">

這樣按說應(yīng)該是可以了,但百度的處理結(jié)果仍然是亂碼,百思而不得其解,偶然當(dāng)中發(fā)現(xiàn)如果$html的值是這樣的話輸出是正常的:

$html = mb_convert_encoding('<title>測(cè)試test</title>', 'gb2312', 'utf-8');
$html = '<meta http-equiv="Content-Type" content="text/html;charset=gb2312">' . $this->html;

這說明,DOM正確識(shí)別了html代碼中的Content-Type描述,即使html是gb2312編碼的,DOM也能夠自動(dòng)轉(zhuǎn)換為正確的代碼。

現(xiàn)在的情況是這樣的:

  • DOM工作正常

  • html已經(jīng)轉(zhuǎn)換為utf8編碼

  • Content-Type描述也已經(jīng)調(diào)整

怎么還是會(huì)出問題呢?先看看下面的Content-Type描述代碼:

$meta = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';

看清楚嘍,如果用$meta直接替換百度html代碼中的那句meta,不會(huì)生效,仍然亂碼;可如果把$meta添加到整個(gè)html代碼前面,也就是<html>前面,輸出就正常了,神奇吧。

于是我就推測(cè),之前百度代碼處理亂碼的原因,可能是在它的html代碼中,meta前面有個(gè)含有中文的<title>,DOM在解析到<title>的時(shí)候,遇到了非ascii字符,而這時(shí)沒有解析到<meta>,DOM不知道整個(gè)html代碼是什么字符集,也就無法正確判斷<title>的編碼,于是糊里糊涂的進(jìn)行了錯(cuò)誤的字符集轉(zhuǎn)換。

為了證實(shí)我的猜測(cè),試著這樣處理一下:只修改<meta>,把定義位置放在<title>前面,把缺少的引號(hào)加上,但是字符集聲明仍然為gb2312,html代碼也不進(jìn)行iconv轉(zhuǎn)換,就像下面這樣(注意為gb2312編碼):

<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=gb2312">
<title>百度一下,你就知道   </title>

執(zhí)行,輸出正常,而且是正常的gb2312編碼,沒有亂碼。所以我的猜測(cè)是正確的,關(guān)于Content-Type的meta聲明一定要放在<title>前面才行。另外上例中如果把nodeValue輸出,是utf8編碼的,也就是DOM的內(nèi)部使用編碼,說明DOM輸入和輸出的時(shí)候都會(huì)進(jìn)行字符集轉(zhuǎn)換(根據(jù)html代碼中的字符集聲明)。

最后,總結(jié)一下,curl讀過來的網(wǎng)頁數(shù)據(jù),全部iconv為utf8編碼,然后把聲明Content-Type的<meta>替換到緊跟在<head>的位置上,再用DOM處理就不會(huì)出現(xiàn)亂碼了。


如對(duì)本文有疑問,請(qǐng)?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會(huì)為你解答??! 點(diǎn)擊進(jìn)入論壇

發(fā)表評(píng)論 (1767人查看0條評(píng)論)
請(qǐng)自覺遵守互聯(lián)網(wǎng)相關(guān)的政策法規(guī),嚴(yán)禁發(fā)布色情、暴力、反動(dòng)的言論。
昵稱:
最新評(píng)論
------分隔線----------------------------

其它欄目

· 建站教程
· 365學(xué)習(xí)

業(yè)務(wù)咨詢

· 技術(shù)支持
· 服務(wù)時(shí)間:9:00-18:00
365建站網(wǎng)二維碼

Powered by 365建站網(wǎng) RSS地圖 HTML地圖

copyright © 2013-2024 版權(quán)所有 鄂ICP備17013400號(hào)