백엔드 개발 PHP 튜토리얼 PHP+Tidy-完美的XHTML纠错+过滤_PHP教程

PHP+Tidy-完美的XHTML纠错+过滤_PHP教程

Jul 21, 2016 pm 03:55 PM
xhtml 기능 그리고 기초적인 사용자 보정 그물 아름다운 입력하다 산출 필터

输入和输出
输入和输出应该说是很多网站的基本功能。用户输入数据,网站输出数据供其他人浏览。

拿目前流行的Blog为例,这里的输入输出就是作者编辑文章后生成博客文章页面供他人阅读。
这里有一个问题,即用户输入通常是不受控制的,它可能包含不正确的格式亦或者含有有安全隐患的代码;而最终网站输出的内容却必须是正确的HTML代码。这就需要对用户输入的内容进行纠错和过滤。

永远不要相信用户的输入
你可能会说:现在到处都是所见即所得的编辑器(WYSIWYG),FCKeditor、TinyMCE...你可能会举出一大堆。是的,它们都可以自动生成标准的XHTML代码,但是作为web开发人员,你肯定听过"永远不要相信用户递交的数据"。

因此对用户输入数据进行纠错和过滤是必需的。

需要更好的纠错和过滤
目前为止我还没见过有让我满意的相关实现,能接触到的通常都是效率低下、效果不太理想,有这样那样的明显缺陷。举个比较知名的例子:WordPress是一种使用非常广泛的blog系统,操作简单功能强大且有丰富的插件支持,但是它集成的TinyMCE和后台一堆有些自作聪明的纠错过滤代码却令人相当头痛,对半角字符的强制替换,过于保守的替换规则等等.....导致像贴一段代码让它正确显示这种需求都很难做到。

这里顺便抱怨一下,这个blog是用WordPress架的,为了让这几篇文章能正确显示代码,网上搜了很多也试用了一些插件,最终还是翻了它的代码把一些过滤规则注释掉才勉强可以显示得体面一点 -.-b 

当然,我不想过多的指责它(wordpress),只是想说明它还可以做的更好。

Tidy是什么,它如何工作?
摘自Tidy ManPage的说明这样描述:

Tidy reads HTML, XHTML and XML files and writes cleaned up markup. For HTML variants, it detects and corrects many common coding errors and strives to produce visually equivalent markup that is both W3C compliant and works on most browsers. A common use of Tidy is to convert plain HTML to XHTML. For generic XML files, Tidy is limited to correcting basic well-formedness errors and pretty printing. 

简单说Tidy是清理HTML代码的,生成干净的符合W3C标准的HTML代码,支持HTML,XHTML,XML。Tidy提供一个库TidyLib,以方便在其他应用中利用Tidy的强大功能。非常幸运,PHP有相应的tidy模块可以使用。

老兄,为什么又是PHP?
呃,这个问题... 惭愧,因为我只会那么点PHP而已 -.-v
不过还好,我这里讲的都不是纯粹的代码,好歹也有些分析的过程,分享这些东西比贴代码有用多了。

PHP中使用Tidy
要在PHP中使用Tidy需要安装Tidy模块,也就是加载tidy.so这个PHP extension,具体过程就略了,纯粹是体力活。最后能在phpinfo()中看到"Tidy support enabled" 就OK。

在这个模块的支持下,PHP中就可以使用Tidy提供的几乎所有的功能。常用的HTML清理是异常轻松的事情,甚至可以生成文档的解析树,像在客户端操作DOM那样的操作HTML的各个Node。下面将会有具体的代码说明,也可以看看PHP官方的相关手册。

纠错和过滤的PHP+Tidy实现
上面说了这么多背景素材,似乎太罗唆了,具体的解决问题的代码才最最直接。

1. 简单的纠错实现

function HtmlFix($html)
{

  if(!function_exists('tidy_repair_string'))
    return $html;
  //use tidy to repair html code

  //repair
  $str = tidy_repair_string($html,
                   array('output-xhtml'=>true),
                   'utf8');
  //parse
  $str = tidy_parse_string($str,
                  array('output-xhtml'=>true),
                  'utf8');
  $s = '';

  $nodes = @tidy_get_body($str)->child;

  if(!is_array($nodes)){
    $returnVal = 0;
    return $s;
  }

  foreach($nodes as $n){
    $s .= $n->value;
  }
  return $s;
}
上面的代码就是对可能不规范的XHTML代码进行清理纠错,输出标准的XHTML代码(输入输出都是UTF-8编码)。实现代码不是最精简的,因为为了配合下面的过滤功能,我写的尽可能细致了一些。

2. 高级实现: 纠错+过滤

功能: 

XHTML的纠错,输出标准的XHTML代码。 
过滤不安全的代码但是不影响内容展示,只是对style/javascript中不安全代码进行清除。 
对超长字符串插入标记以实现浏览器兼容的自动换行功能,相关文章可参考网页中超长文字的断行问题。 
function HtmlFixSafe($html)
{

  if(!function_exists('tidy_repair_string'))
    return $html;
  //use tidy to repair html code

  // tidy 的参数设定
  $conf = array(
                'output-xhtml'=>true
                ,'drop-empty-paras'=>FALSE
                ,'join-classes'=>TRUE
                ,'show-body-only'=>TRUE
                );

 //repair
  $str = tidy_repair_string($html,$conf,'utf8');
  //生成解析树
  $str = tidy_parse_string($str,$conf,'utf8');

  $s ='';

  //得到body节点
  $body = @tidy_get_body($str);

  //函数 _dumpnode,检查每个节点,过滤后输出
  function _dumpnode($node,&$s){

   //查看节点名,如果是<script> 和<style>就直接清除 <BR> switch($node->name){ <BR> case 'script': <BR> case 'style': <BR> return; <BR> break; <BR> default: <BR> } <br><br> if($node->type == TIDY_NODETYPE_TEXT){ <BR> /* <BR> 如果该节点内是文字,做额外的处理: <BR> 过长文字的自动换行问题; <BR> 超链接的自动识别(未实现) <BR> */ <BR> // insert <wbr> <BR> $s .= HtmlInsertWbrs($node->value,30,'','&?/\'); <br><br> // auto links ??? *** TODO *** <BR> return; <BR> } <br><br> //不是文字节点,那么处理标签和它的属性 <BR> $s .= '<'.$node->name; <br><br> //检查每个属性 <BR> if($node->attribute){ <BR> foreach($node->attribute as $name=>$value){ <br><br> /* <BR> 清理一些DOM事件,通常是on开头的, <BR> 比如onclick onmouseover等.... <BR> 或者属性值有javascript:字样的, <BR> 比如href="javascript:"的也被清除. <BR> */ <BR> if(strpos($name,'on') === 0 <br><br> stripos(trim($value),'javascript:') ===0 <BR> ){ <BR> continue; <BR> } <br><br> //保留安全的属性 <BR> $s .= ' '.$name.'="'.HtmlEscape($value).'"'; <br><br> } <BR> } <br><br> //递归检查该节点下的子节点 <BR> if($node->child){ <br><br> $s .= '>'; <br><br> foreach($node->child as $child){ <BR> _dumpnode($child,$s); <BR> } <br><br> //子节点处理完毕,闭合标签 <BR> $s .= '</'.$node->name.'>'; <BR> }else{ <br><br> /* <BR> 已经没有子节点了,将标签闭合 <BR> (事实上也可以考虑直接删除掉空的节点) <BR> */ <BR> if($node->type == TIDY_NODETYPE_START) <BR> $s .= '></'.$node->name.'>'; <BR> else <BR> /* <BR> 对非配对标签,比如<hr/> <br/> <img / alt="PHP+Tidy-完美的XHTML纠错+过滤_PHP教程" >等 <BR> 直接以 />闭合之 <BR> */ <BR> $s .= '/>'; <BR> } <BR> } <BR> //函数定义end <br><br> //通过上面的函数 对 body节点开始过滤。 <BR> if($body->child){ <br><br> foreach($body->child as $child) <BR> _dumpnode($child,$s); <BR> }else <BR> return ''; <br><br> return $s; <BR>} <BR>上面代码中注释应该比较详细,工作原理就配合代码看吧。 <BR>更严格的过滤也很容易扩展,比如实现文中的链接自动识别。 <br><br><BR>一点补充 <br><br>如果你看过我之前写的网页中超长文字的断行问题,你可能发现上面代码中处理自动换行的函数有所不同: <br><br>之前介绍的是HtmlEscapeInsertWbrs(),而上面使用的是HtmlInsertWbrs()。 <br><br>这里要做一下解释: <BR>HtmlEscapeInsertWbrs()要求输入的字符串未作特殊字符转义的,也就是没有经过htmlspecialchars()对<>&等作<>&处理的。因为函数内部有专门的处理。 <BR>而在处理经Tidy处理过后的文字节点的时候,因为Tidy的关系,已经自动把<>&等字符作相应的<>&转义,因此需要用一个专门的函数避免重复的转义,这个函数就是HtmlInsertWbrs(),从名字上就知道它只插入<wbr>标记,不做额外工作。 <br><br>那么你可能有个问题: <BR>如果<wbr>被插入到HTML标签中间,比如在<div>或者>的中间插入了<wbr>,变成<d<wbr>iv>和&<wbr>gt;,那就会影响到原始信息的展示。 <br><br>没错,的确是个新问题,不过使用一些技巧就可以有效解决: <br><br>因为我们处理的是Tidy得到的文字节点,意味着不可能碰到HTML标签,因此不会碰到在标签中间插入<wbr>的情况。 <BR>对于第二种情况,转义后的字符都是&xxxxx;这样的形式,那么只要在1所有&符号前面都插入<wbr>标记就可以了(注意看调用时的第四个参数),因为下一个<wbr>标记将会插在30(以上面代码中实际调用的第二个参数为例)个字符之后,这个已经2远远大于xxxxx的长度。这样由上面1、2两点可以保证不会插到转义字符的中间。 <BR>下面给出HtmlInsertWbrs()的PHP实现: <br><br>function HtmlInsertWbrs($str, $n=10, <BR> $chars_to_break_after='',$chars_to_break_before='') <BR>{ <BR> $out = ''; <BR> $strpos = 0; <BR> $spc = 0; <BR> $len = mb_strlen($str,'UTF-8'); <BR> for ($i = 1; $i < $len; ++$i) { <BR> $prev_char = mb_substr($str,$i-1,1,'UTF-8'); <BR> $next_char = mb_substr($str,$i,1,'UTF-8'); <BR> if (_u_IsSpace($next_char)) { <BR> $spc = $i; <BR> } else { <BR> if ($i - $spc == $n <br><br> mb_strpos( $chars_to_break_after, <BR> $prev_char,0,'UTF-8' ) <BR> !== FALSE <br><br> mb_strpos( $chars_to_break_before, <BR> $next_char,0,'UTF-8') <BR> !== FALSE <BR> ) { <BR> $out .= mb_substr($str,$strpos, <BR> $i-$strpos,'UTF-8') <BR> . '<wbr>'; <BR> $strpos = $i; <BR> $spc = $i; <BR> } <BR> } <BR> } <BR> $out .= mb_substr($str,$strpos,$len-$strpos,'UTF-8'); <BR> return $out; <BR>} <BR>... <BR>Ok,先写这么多,相关的资料在文中都有链接。 <BR>下次想到再补充。 <BR> </script>

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/318191.htmlTechArticle输入和输出 输入和输出应该说是很多网站的基本功能。用户输入数据,网站输出数据供其他人浏览。 拿目前流行的Blog为例,这里的输入输...
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Xiaohongshu 계정을 사용하여 사용자를 찾는 방법은 무엇입니까? 내 휴대폰 번호를 찾을 수 있나요? Xiaohongshu 계정을 사용하여 사용자를 찾는 방법은 무엇입니까? 내 휴대폰 번호를 찾을 수 있나요? Mar 22, 2024 am 08:40 AM

소셜 미디어의 급속한 발전으로 Xiaohongshu는 가장 인기 있는 소셜 플랫폼 중 하나가 되었습니다. 사용자는 Xiaohongshu 계정을 만들어 자신의 개인 신원을 표시하고 다른 사용자와 소통하고 상호 작용할 수 있습니다. 사용자의 Xiaohongshu 번호를 찾으려면 다음의 간단한 단계를 따르세요. 1. Xiaohongshu 계정을 사용하여 사용자를 찾는 방법은 무엇입니까? 1. Xiaohongshu 앱을 열고 오른쪽 하단에 있는 "검색" 버튼을 클릭한 다음 "메모" 옵션을 선택합니다. 2. 노트 목록에서 찾고자 하는 사용자가 게시한 노트를 찾아보세요. 클릭하시면 메모 세부정보 페이지로 이동합니다. 3. 노트 상세페이지에서 해당 사용자의 아바타 아래 '팔로우' 버튼을 클릭하여 해당 사용자의 개인 홈페이지로 진입합니다. 4. 이용자 개인 홈페이지 우측 상단의 점 3개 버튼 클릭 후 '개인정보' 선택

vivox100s와 x100의 차이점: 성능 비교 및 ​​기능 분석 vivox100s와 x100의 차이점: 성능 비교 및 ​​기능 분석 Mar 23, 2024 pm 10:27 PM

vivox100s와 x100 휴대폰은 모두 in vivo 휴대폰 제품군의 대표적인 모델입니다. 두 휴대폰은 각각 서로 다른 시대의 vivo 첨단 기술 수준을 대표하므로 디자인, 성능, 기능 면에서 일정한 차이가 있습니다. 이번 글에서는 소비자들이 자신에게 꼭 맞는 휴대폰을 선택할 수 있도록 두 휴대폰을 성능비교와 기능분석 측면에서 자세히 비교해보겠습니다. 먼저 vivox100s와 x100의 성능 비교를 살펴보겠습니다. vivox100s에는 최신 기술이 탑재되어 있습니다.

셀프미디어란 정확히 무엇인가? 주요 특징과 기능은 무엇입니까? 셀프미디어란 정확히 무엇인가? 주요 특징과 기능은 무엇입니까? Mar 21, 2024 pm 08:21 PM

인터넷의 급속한 발전으로 셀프미디어라는 개념은 사람들의 마음속에 깊이 뿌리내렸습니다. 그렇다면 셀프미디어란 정확히 무엇인가? 주요 특징과 기능은 무엇입니까? 다음에는 이러한 문제를 하나씩 살펴보겠습니다. 1. 셀프미디어란 정확히 무엇인가? We-media는 이름에서 알 수 있듯이 당신이 미디어라는 뜻입니다. 개인이나 팀이 인터넷 플랫폼을 통해 콘텐츠를 독립적으로 생성, 편집, 출판 및 전파할 수 있는 정보 매체를 말합니다. 신문, 텔레비전, 라디오 등과 같은 전통적인 미디어와 달리 셀프 미디어는 더욱 상호작용적이고 개인화되어 있어 모든 사람이 정보의 생산자이자 전파자가 될 수 있습니다. 2. 셀프미디어의 주요 특징과 기능은 무엇입니까? 1. 낮은 문턱: 셀프미디어의 등장으로 미디어 산업에 진출하기 위한 문턱이 낮아졌습니다. 더 이상 번거로운 장비와 전문팀이 필요하지 않습니다.

PHP는 어떤 용도로 사용되나요? PHP의 역할과 기능 살펴보기 PHP는 어떤 용도로 사용되나요? PHP의 역할과 기능 살펴보기 Mar 24, 2024 am 11:39 AM

PHP는 웹 개발에 널리 사용되는 서버 측 스크립팅 언어입니다. 주요 기능은 HTML과 결합하면 풍부하고 다채로운 웹 페이지를 생성할 수 있습니다. PHP는 강력하며 다양한 데이터베이스 작업, 파일 작업, 양식 처리 및 기타 작업을 수행하여 웹 사이트에 강력한 상호 작용과 기능을 제공합니다. 다음 기사에서는 자세한 코드 예제를 통해 PHP의 역할과 기능을 자세히 살펴보겠습니다. 먼저, PHP의 일반적인 용도를 살펴보겠습니다: 동적 웹 페이지 생성: P

2023년 메이디그룹 매출은 전년 동기 대비 8.18% 증가한 3,720억 위안, 배당금은 208억 위안이 될 전망이다. 2023년 메이디그룹 매출은 전년 동기 대비 8.18% 증가한 3,720억 위안, 배당금은 208억 위안이 될 전망이다. Mar 28, 2024 pm 02:42 PM

3월 28일 이 웹사이트의 소식에 따르면 Midea Group은 최근 2023년에 3,720억 3,700만 위안의 영업이익을 달성할 것이라고 발표했습니다. 이는 전년 대비 8.18% 증가한 상장 기업 주주들에게 귀속되는 순이익은 337억 2,000만 위안입니다. , 전년 대비 14.10% 증가, 기본 주당 이익은 4.93위안으로 전년 대비 13.59% 증가했습니다. 메이디그룹은 10주당 30위안의 현금 배당금을 지급할 계획이라고 밝혔다. 이번 배당 총액은 208억 위안으로 모회사 순이익의 61.5% 이상을 차지해 최고 수준이다. 역사상 배당률. 2023년 재무 보고서 데이터에 따르면 Midea의 3대 ToB 사업, 신에너지 및 산업 기술, 로봇 및 자동화, 스마트 빌딩 전략 기술의 매출은 279억 위안(전년 대비 29% 증가)이 될 것으로 나타났습니다. 각각 311억 위안(전년 대비 증가)이다.

VSCode 이해: 이 도구는 어떤 용도로 사용됩니까? VSCode 이해: 이 도구는 어떤 용도로 사용됩니까? Mar 25, 2024 pm 03:06 PM

"VSCode 이해: 이 도구는 어떤 용도로 사용됩니까?" 》프로그래머로서 초보자이든 숙련된 개발자이든 코드 편집 도구를 사용하지 않으면 할 수 없습니다. 많은 편집 도구 중에서 Visual Studio Code(약칭 VSCode)는 가볍고 강력한 오픈 소스 코드 편집기로 개발자들 사이에서 매우 인기가 높습니다. 그렇다면 VSCode는 정확히 어떤 용도로 사용되나요? 이 기사에서는 VSCode의 기능과 사용법을 자세히 살펴보고 독자에게 도움이 되는 구체적인 코드 예제를 제공합니다.

GateToken(GT) 화폐란 무엇인가요? GT 코인 기능 및 토큰 경제 소개 GateToken(GT) 화폐란 무엇인가요? GT 코인 기능 및 토큰 경제 소개 Jul 15, 2024 pm 04:36 PM

GateToken(GT) 화폐란 무엇인가요? GT(GateToken)는 GateChain 체인의 기본 자산이자 Gate.io의 공식 플랫폼 통화입니다. GT 코인의 가치는 Gate.io 및 GateChain 생태계의 발전과 밀접한 관련이 있습니다. GateChain이란 무엇입니까? GateChain은 2018년에 탄생했으며 Gate.io가 출시한 차세대 고성능 퍼블릭 체인입니다. GateChain은 사용자의 온체인 자산의 보안을 보호하고 편리한 분산 거래 서비스를 제공하는 데 중점을 두고 있습니다. GateChain의 목표는 기업 수준의 안전하고 효율적인 분산형 디지털 자산 저장, 유통 및 거래 생태계를 구축하는 것입니다. 게이트체인에는 원본이 있습니다.

모바일 및 Jiaqin 앱의 용도는 무엇입니까? 모바일 및 Jiaqin 앱의 용도는 무엇입니까? Mar 27, 2024 pm 09:01 PM

모바일 Hejiaqin APP는 가족 관리, 지능형 제어 및 가족 커뮤니케이션을 통합하는 포괄적인 소프트웨어입니다. 지능적이고 편리한 조작을 통해 사용자를 위한 편안하고 지능적이며 조화로운 가정 환경을 만드는 것을 목표로 합니다. 이 애플리케이션을 통해 사용자는 집에서 다양한 스마트 기기를 쉽게 제어 및 관리할 수 있으며, 스마트 라이프가 선사하는 편리함을 누릴 수 있습니다. 그렇다면 모바일 및 Jiaqin 앱의 구체적인 기능은 무엇입니까? 이에 대해 더 알고 싶은 사용자는 이 기사를 따라 더 자세히 알아볼 수 있습니다! 모바일 및 Jiaqin 앱 사용 방법에 대한 튜토리얼: 모바일 및 Jiaqin 앱의 용도는 무엇입니까? IT를 몰라도 쉽게 네트워크를 관리할 수 있습니다. 2. 스마트 제품이 아무리 많아도 하나면 충분합니다. 3. 집에서 수천 마일 떨어져 있어도 "집에 가서" 시청할 수 있습니다. 4. 풍부한 기능, 스마트한 생활을 즐기세요.

See all articles