3 回答
TA贡献1872条经验 获得超4个赞
如果您想按原样保存来自作者的 HTML 代码并将其作为“工作”HTML 代码输出到页面上,则不要使用任何 HTML 编码/解码功能。将接收到的内容“按原样”保存在数据库中,稍后用 正常“按原样”输出 HTML echo,就像它是没有 HTML 代码的“正常”内容一样。请记住,这是一个巨大的安全问题,因为作者可以使用他们的 HTML 编辑器软件编写他们喜欢的任何 HTML 代码。他们可以添加任何 HTML 代码,包括 javascript 代码。你被警告了!
对于可以替换为各自字符(如óto ó)的 HTML 实体,使用该get_html_translation_table()函数获取这些字符的映射。HTML_SPECIALCHARS从映射中减去映射,HTML_ENTITIES因为您只需要非 HTML 相关的映射。使用array_diff()方法来做到这一点。使用映射启动一个简单的str_replace()调用,用它们的字符替换所有实体。
$text = '<b>Ramón</b>, formula <code>a < b</code>, <a href="link.html">some link</a> content. Some spaced words.';
$mapping = get_html_translation_table(HTML_ENTITIES);
$mapping = array_diff($mapping, get_html_translation_table());
echo $text."\n";
echo str_replace(array_values($mapping), array_keys($mapping), $text);
出于测试目的,这将生成以下输出:
<b>Ramón</b>, formula <code>a < b</code>, <a href="link.html">some link</a> content. Some spaced words.
<b>Ramón</b>, formula <code>a < b</code>, <a href="link.html">some link</a> content. Some spaced words.
如您所见,与 HTML 相关的实体保持为实体,而其他实体被其字符替换。在将原始 HTML 代码保存到数据库之前应用此转换。
对于数据库中已经解码的 HTML 内容:你不走运。没有万无一失的方法可以将与 HTML 相关的字符“重新编码”<回它们的<实体,因为您不知道哪个是/是 HTML 代码,哪个是/是“内容”。你可以做出很好的猜测,比如
文本< b应该是< b并且文本<b应该保持原样,因为那是 HTML 代码。
但这仍然只是(好/坏)猜测。
TA贡献1865条经验 获得超7个赞
这不是奇怪的行为;这是您要求计算机执行的操作。您要求它存储 HTML 文档,然后为了进行搜索工作,您要求它解码HTML 文档中的所有实体,导致(在某些情况下)文档的含义发生变化,并导致(在最坏的情况下)您的文件将失效。
不要将 HTML 存储在数据库中。您应该生成用于呈现的 HTML,而不是用于存储。以语义方式存储您的数据。(MySQL 具有文本搜索功能;HTML 只是让这更难。)
以演示标记格式存储它,并剥离所有上下文信息(通过解码实体)给您留下了无法可靠使用的数据。当您拥有 时<,您现在拥有<,并且在批量解码所有实体之前无法知道哪个是哪个。
你把牛奶放入水中搅拌。你不能把水弄回来。
你需要明白你的方法从根本上是有缺陷的。您应该检查决策过程中的每个步骤,并再次向自己解释。
然后将漂亮的普通字符串存储在您的数据库中,而不是 HTML。
如果由于某种原因这是不可能的,至少停止解码实体。这会使搜索变得更加困难,因为简单的文本搜索是不够的,但实际上您的搜索例程应该是 HTML 感知的,以便获得正确的结果,所以您最好做对。
tl;博士:
很明显,浏览器将“<”解释为打开标签。
因为它是。这就是<在 HTML 中所做的。
很好,<但后来你逃脱了它。
TA贡献1833条经验 获得超4个赞
这似乎并不容易,但咨询其他想法来解决类似问题,我编写了这个脚本,它解决了我将任何 HTML 内容存储到 MariaDB/MySQL 数据库(UTF-8 表)并检索以显示为 UTF-8 网页而无需问题。在我的例子中,用户从文字处理器粘贴文本,很多时候他们有印刷字符(双引号和单引号),我们用非印刷字符替换它们,让用户也可以搜索它们。
function PREPARE_TO_STORE($HTML_Code)
{
$V_Matches = Array();
$Token = '###TOKEN_HTML###';
// We will replace typographic characters by non typographical ones and will remain "<" as an HTML entity
$V_Search = array( "‘", "’", "”", "“", "″", "<");
$V_Replace = array( "'", "'", '"', '"', '"', "<");
preg_match_all("@<[^>]*>@", $HTML_Code, $V_Matches);
$V_Content = preg_replace("@(<[^>]*>)@", $Token, $HTML_Code); // $V_Content will contain string between HTML tags
$V_Content = explode($Token, $V_Content); // Splits HTML from content
for ($i=0; $i<count($V_Content); $i++) // Decoding all entities
{
$V_Content[$i] = html_entity_decode($V_Content[$i], ENT_QUOTES | ENT_HTML5, "UTF-8");
$V_Content[$i] = str_replace($V_Search, $V_Replace, $V_Content[$i]);
}
$V_Content = join($Token, $V_Content); // Join again HTML tags with content
for ($i=0; $i<count($V_Matches[0]); $i++)
$V_Content = preg_replace("@$Token@", $V_Matches[0][$i], $V_Content, 1);
return $V_Content;
}
$HTML_to_store_in_db = mysqli_real_escape_string($link, PREPARE_TO_STORE($anuncio));
// Here your own code to store $HTML_to_store_in_db in your database
要显示我们存储的 HTML 代码,只需执行以下操作:
echo $HTML_data_retrieved_from_DB;
但如果您的网页不是 UTF-8,也许您需要这样做
echo htmlspecialchars($HTML_data_retrieved_from_DB, ENT_QUOTES | ENT_HTML5, "webpage_coding"); // "webpage_coding" is your character coding, in our case, UTF-8
当然,欢迎任何建议、问题或修复
- 3 回答
- 0 关注
- 193 浏览
添加回答
举报
