保留现有HTML实体不变,但转换双引号和单引号

时间:2018-10-16 19:32:57

标签: php html html-entities htmlspecialchars

我正在使用PHP代码生成我的元描述标签,如下所示:

<meta name="description" content="<?php
echo $this->utf->clean_string(word_limiter(strip_tags(trim($paperResult['file_content'])),27));
?>


这是元描述输出的示例:

<meta name="description" content="blah blah &#182; &#8230; blah blah "words in quotation marks" blah blah "more words in quotation marks" blah blah" />

该示例元描述中的两个HTML实体是一个段落符号(&#182;),后跟一个省略号(&#8230;)。它们已经在源文本中以HTML实体形式出现,因此我希望它们保持不变。问题是我还需要描述中的引号将其转换为&quot;,以防止meta标记损坏。我尝试的每种组合/配置都不起作用或无法正常运行,因为我弄错了代码。例如,当我尝试以下代码时,引号会根据需要转换为它们的HTML实体,但是段落符号和省略号实体会中断,因为现有HTML实体开头的与号字符已转换为&amp; 。剩下的&#182;&amp;#182;)和&#8230;&amp;#8230;)都是损坏的:

 echo $this->utf->clean_string(word_limiter(htmlspecialchars(strip_tags(trim($paperResult['file_content']))),27));

从字面上看,我已经尝试了好几天了。我已经在Stack Overflow中进行了广泛搜索,但无济于事。我只需要现有的HTML实体保持不变,并且将引号转换为它们的HTML实体(&quot;)。我研究了ENT_QUOTES option,并且知道解决方案可能存在于其中,但是我不知道如何将其合并到我的特定代码行中。我希望您的PHP专家对这个受折磨的灵魂有怜悯之心!非常感谢您的帮助。

谢谢!

2 个答案:

答案 0 :(得分:2)

如果它是“内容”属性的内容,则可以执行此操作

$str = 'blah blah &#182; &#8230; blah blah "words in quotation marks" blah blah "more words in quotation marks" blah blah';
echo htmlentities($str, ENT_QUOTES, "UTF-8", false);

输出

blah blah &#182; &#8230; blah blah &quot;words in quotation marks&quot; blah blah &quot;more words in quotation marks&quot; blah blah

Sandbox

这里的关键是第四个参数

  

字符串htmlentities(字符串$ string [,int $ flags = ENT_COMPAT | ENT_HTML401 [,字符串$ encoding = ini_get(“ default_charset”)[,bool $ double_encode = TRUE]]])

特别是

  

double_encode (关闭double_encode)时,PHP将不会对现有的html实体进行编码。默认是转换所有内容。

那样,它不会对&符号进行双重编码。

htmlspecialchars也有一个双编码参数。

  

htmlspecialchars(字符串$ string [,int $ flags = ENT_COMPAT | ENT_HTML401 [,字符串$ encoding = ini_get(“ default_charset”)[,bool $ double_encode = TRUE]]])

$str = 'blah blah &#182; &#8230; blah blah "words in quotation marks" blah blah "more words in quotation marks" blah blah';
echo htmlspecialchars($str, ENT_QUOTES, "UTF-8", false);

输出

blah blah &#182; &#8230; blah blah &quot;words in quotation marks&quot; blah blah &quot;more words in quotation marks&quot; blah blah

Sandbox

如果是整个标记,则必须拉出内容并对其进行修改,然后替换它以保留<>,但问题尚不清楚如果是这样的话。

PS htmlspecialcharshtmlentities之间并没有太大的区别,它主要与é累加和其他类似的重音有关,htmlentities也会对它们进行编码我没记错。

更新

  

我需要将解决方案整合到我特定的PHP代码格式中(例如,一行保留我现有功能的PHP),就像miken32在上面的出色表现一样

要将其放入您的代码中,

<meta name="description" content="<?=htmlspecialchars(word_limiter(trim($paperResult['file_content']),27),ENT_QUOTES,"UTF-8",false);?>"/>

UPDATE2

使用preg_replace('/[\r\n]+/', ' ', $string)会将\r\n\n删除一次或多次+。但是用这种方式preg_replace(['/[\r\n]+/', '/\s+/'], ' ', $string)可能会更好。这也将消除空格上的运行。

 <meta name="description" content="<?=htmlspecialchars(word_limiter(preg_replace('/[\r\n]+/', ' ', trim($paperResult['file_content'])),27),ENT_QUOTES,"UTF-8",false);?>"/>

基本上,这是使您可能想在word_limiter之前(无论是什么)都简短的文本的任何内容。以及使它更长的任何事情,例如将"更改为&quote;,您可能想在之后执行(也许)。对我来说似乎更合逻辑。

干杯!

答案 1 :(得分:1)

我不确定,因为您没有告诉我们所有其他功能,但是看来您可以这样做:

<meta name="description" content="<?=htmlspecialchars(html_entity_decode(word_limiter($paperResult['file_content'], 27)))?>"/>

因此,请限制字数,将所有实体转换为字符,然后将所有特殊字符重新转换为实体。出于安全性考虑,无需剥离标签,因为htmlspecialchars将确保任何输出都可以安全地包含在HTML中。