2012-07-26 121 views
4

我使用php的整洁库来“清理和修复”一些来自用户输入的html。php tidy奇怪的行为

一切工作正常,但我遇到了一个问题,我无法弄清楚它是什么原因。我的代码是这样的:

$tidy = new tidy(); 

    $tidy_options = array(
     'hide-comments' => true,'tidy-mark' => false, 'indent' => false, 
     'new-blocklevel-tags' => 'article,footer,header,hgroup,output,progress,section,video', 
     'new-inline-tags' => 'audio,details,time,ruby,rt,rp', 
     'drop-empty-paras' => false, 
     'doctype' => '<!DOCTYPE HTML>', 
     'sort-attributes' => 'none', 'vertical-space' => false, 
     'output-xhtml' => true,'wrap' => 180, 
     'wrap-attributes' => false, 
     'break-before-br' => false, 
     'show-body-only' => true 
     ); 
$data = $tidy->repairString($data, $tidy_options, 'UTF8'); 
echo $data; 

这适用于各种投入,当我试图使用HTML embeding SWF文件除外。
所以,我试试这个代码:

<object data="http://the_swf_file_url" type="application/x-shockwave-flash" width="853" height="520"> 
    <param name="movie" value="http://the_swf_file_url"> 
</object> 

但repairString条纹关闭所有的它,并返回一个空字符串。
最奇怪的是:
- 如果我上述沿输入一些文字,所以输入就像Hello world<object...>...</object>然后正常工作。
- 或如果我指定'show-body-only' => false它也正常工作!

任何线索为什么会发生这种情况? 在此先感谢。

编辑:试图pankar的建议有保留设置实体为true,但没有运气...

回答

6

问题是您正在尝试处理HTML 片段

当您这样做时,文档的其余部分是推断。如果您将配置保留为默认配置,并且只输出一段文本,那么您将看到DOCTYPE,html,headbody标签,您没有给它。它推断这些标签必须存在。

这里的问题是,HTML specification regarding objects指出:

对象元件也可以出现在头元件的内容。

当你的片段的位置被推断,它把它放在它可以发生首位。这意味着整洁将它放在head标签中。

show-body-only影响您的输出的原因是因为您的片段没有被放置在body


但是当你添加一些文字,它迫使你的片段到 body标签。这是因为原始文本 不允许head标记中。所以你的片段的逻辑推断位置在 body

在我看来,最适合您的选择是将所有代码片段注入“模板”文档,然后再解析出来。你可以用DOMDocument很容易地做到这一点。

第二种解决方案是注入一个标记值,以便在仅显示身体时再去除。

I.e.

____MY_MAGIC_TOKEN____ 
<object ...></object> 

然后你可以在之后再去掉它。

+0

嗨莱特,谢谢你打扰我的问题,并提供足够的解释性答案。现在我得到了这个问题,并且可以提供一个解决方案(您的提议似乎都是合法的)。我可能从来没有想过,'OBJECT元素也可能出现在HEAD元素的内容中.' – CrisDeBlonde 2012-08-07 20:21:55

+0

没问题,*标准*是棘手的bug子手。每个人都想坚持他们,但大多数人不知道(或关心)他们的内容。经过一番尝试和一个“跆拳道”的时刻,我必须自己去看看,以确保它! – Leigh 2012-08-07 20:28:01

3

尝试指定 configuration选项 preserve-entitiestrue(默认为 false)。

编辑

秒(更透彻)的想法。这是一个预期的行为。通过将show-body-only设置为true,您可以告知tidy输出xhtml已处理文档的正文部分。

此设置实际上将忽略文档的<head>中的所有内容。 <object>组件是<head>的子项。您可以通过简单地指定

$data = "<title>My Site</title>"进行验证。

输出将再次为空。

您试图将前缀文本标记为<object>标记只是简单地哄骗整洁,因为它认为这些数据必须作为页面主体的一部分进行处理,从而进行显示。

希望这次有更多的帮助。

+0

嗨潘卡尔,谢谢你的回复。我尝试了你的建议,但没有再次运气。这是否意味着整洁认为我的代码' ...'不是格式正确的实体?为什么然后如果我输入一些其他文字以及我的对象代码,它工作正常? – CrisDeBlonde 2012-07-26 13:31:08

+0

潘卡尔,再次感谢与我的问题打扰。我理解你所描述的“仅show-body-only”=> true'部分,这就是所需的行为。我不明白的是'''组件是'''的孩子!我是否错过了像这样重要的事情?我找不到任何文件来验证您的声明。当然,如果这是真的,那么我的问题的解决方案是显而易见的。你能详细解释一下吗?非常感谢您的时间! :) – CrisDeBlonde 2012-07-26 23:26:53

+0

我理解你的担忧,我知道这没有意义,但它似乎是一个整洁的限制(可能认为它需要放在头上的元数据信息?)。我最终相信这是一个错误! – pankar 2012-07-27 08:21:59