欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  php教程

PHP版的jQuery

程序员文章站 2022-04-29 13:20:49
...

个人认为,对于Web前端程序员和跟HTML和CSS打交道的人来说,jQuery是有史以来最伟大的发明。jQuery的出现使Web程序员的开发效率突飞猛进,不亚于工业革命给人类生产力带来的提升。 但问题在在于,只有前端程序员可以利用jQuery的强力,他们可以用它分析HTML

个人认为,对于Web前端程序员和跟HTML和CSS打交道的人来说,jQuery是有史以来最伟大的发明。jQuery的出现使Web程序员的开发效率突飞猛进,不亚于工业革命给人类生产力带来的提升。

但问题在在于,只有前端程序员可以利用jQuery的强力,他们可以用它分析HTML,根据CCS类,HTML属性,CSS规则等各种选择器来查询、获取、操作HTML里的任何一个元素。而作为后端(服务端)程序员来说,他们同样需要分析HTML内容,从HTML中提取符合要求的HTML片段、获取某个符合条件的属性值等。

遇到这种情况,后端程序员通常的做法就是用正则表达式、或用XML解析器。这些做法非常的笨拙,不方便,效率低下。所以,对于在服务器端解析HTML,每个后端程序员都极力避免。

我是一个PHP程序员,最近就遇到了这样的一个任务,需要在服务器端解析HTML,将里面的标题名称和链接提取出来。最初我想开发一个小程序逐行分析HTML,捕捉关键字,或用正则表达式。但简单分析了一下,这样做实在不可取。因为我也是个Web程序员,经常使用jQuery解析HTML页面上的内容。如果这个任务放到浏览器端执行,太简单了,只需要一句代码:jQuery('.title').each(...);,如何能在服务器端也能像jQuery那样进行HTML DOM查询呢?

实际上,在服务器端有不少具有jQuery功能的PHP程序库。在网上稍微做了点功夫,就搜到了10几个声称都能解析HTML的PHP工具。但经过试验,大部分都多少有这样或那样的缺陷,而且都有一个通病,就是中文乱码问题。最终,我选用了一个叫做phpQuery的工具包。

实际上,使用phpQuery这个PHP程序库也是很不情愿的,因为这个程序已经很多年没人维护更新了。但比起其它几个类似功能程序库,例如Zend_Dom、QueryPath、SimpleHtmlDom,它算是好的。

phpQuery的接口很丰富,但很简单。一个基本的用法是这样的:

$list = phpQuery::newDocumentFileHTML('http://www.webhek.com')->find('h2.title a');
foreach($list as $e) { 
	$title = $e->nodeValue;
	$url = $e->getAttribute('href');
}

上面的find()方法返回的对象是PHP官方扩展库中的DOM对象,也就是说,phpQuery是一个基于PHP原生的DOM对象的HTML/XML解析器,这样做的好处是,效率很高。相反,像SimpleHtmlDom这样也是分析HTML/XML的程序库,但没有基于PHP原生DOM对象,当分析大数据量时,很容易产生性能问题,所以不推荐使用。

之前说了,所有的这样类似jQuery的能分析HTML DOM的PHP程序库都一个相同的通病:遇到中文会有乱码。我在使用phpQuery的过程中也遇到了这个问题。

首先PHP中的中文本身就是个问题,而PHP的DOM对象处理中文的方式也是有争议的。官方文档是说,这个DOM扩展包使用的是UTF-8编码,当遇到 ISO-8859-1 编码的文本时,使用 utf8_encode() 和 utf8_decode() 编码和解码,遇到其它编码时,使用Iconv函数进行转码。但现实情况比这要复杂的多。网上有很多意见认为在遇到DOM乱码时,在HTML代码里的标记前加入就行了。但这种方法有时候也不灵。

我在解决phpQuery的中文乱码问题也是反复尝试才最后搞定的,没有任何理论依据。就像是有个程序员的笑话:这段代码不好用,我不知道为什么。这段代码好用,我也不知道为什么。:(

首先我是在台式机上开发测试的,是Window7,这种环境下会出现两种情况,一种情况是HTML的字符集是GBK/gb2312,一种情况是字符集是UTF-8。奇怪的是,两个同样是gb2312字符集的不同页面,用phpQuery解析后,一个会有乱码,一个没有乱码。同样,两个同样是UTF-8字符集的不同页面,也会出现这种情况。所有,对我来说,没有规律可言。我只能说,这两种方法能解决phpQuery使用过程中出现的乱码,但何时使用哪种?我不知道,你只能两个都试一下,会有一个好用。

所以,有乱码出现时,首先使用第一种方案:

//仍然使用上面的代码例子:
$list = phpQuery::newDocumentFileHTML('http://www.webhek.com')->find('h2.title a');
foreach($list as $e) { 
	$title = $e->nodeValue;
	//进行GBK转码
	$title = iconv("UTF-8","GBK",  $title);
}

如果不行,使用第二种方案:

//仍然使用上面的代码例子:
//指定GBK字符集参数
$list = phpQuery::newDocumentFileHTML('http://www.webhek.com','GBK')->find('h2.title a');
foreach($list as $e) { 
	$title = $e->nodeValue;
}

第一种方案中要使用iconv函数进行转码,第二种方案中不需要iconv转码,但需要在newDocumentFileHTML方法上提供“GBK字符集”。

还有一点很重要,在使用iconv函数转码是,一定要使用GBK,而不是使用gb2312,如果使用gb2312,iconv函数会很容易发生非法字符的报错,使得转码失败。

我以为有了这两种方案护航后,乱码问题再不会出现。可是,你要知道,做程序员很容易的心脏病的。当我把这些代码部署到linux服务器上时,乱码依旧。抓狂。

没办法,程序员的生活就是这样。经过调试,发现,在linux服务器上,采用第二种方案的部分网页仍然正常,但使用第一种方案时,需要去掉iconv函数转码。

下辈子一定不要做程序员。