PHP,html_entity_decode和htmlspecialchars_decode不起作用

时间:2012-07-01 11:30:41

标签: php utf-8

Gah,我从不喜欢PHP,它是如此“不纯洁”......

现在我必须使用它并且我遇到了问题:主要是html_entity_decodehtmlspecialchars_decode似乎都不适合我。我看完了这个论坛,一无所获。它似乎无处不在,只是在这里不起作用......

我正在将一部电影的标题发送到一个数据库,所有数据都被编码,然后当我从数据库中获取它时,我正在解码它:

$title = html_entity_decode($row['Title']);

然后:

"title":"'.$title.'"

它是我用PHP创建的JSON对象的一部分。虽然当我查看该特定对象的属性时,它没有解码其标题,实际上根本没有任何变化。我尝试了问题标题中所述的两个函数,并尝试了像UTF-8这样的编码,还有一些选项,如ENT_QUOTES或ENT_COMPAT,但它仍然不起作用。

有人可以告诉我为什么PHP不会服从我吗?

编辑: 以下是我在那里做的全部内容:

echo 'var serverVideos = [';
while($row = mysql_fetch_array($result))
{
    $currentRow++;
    $data = array('posterSrc' => $row["Poster_name"],
        'videoSrc' => $row["Video_name"],
        'videoType' => $row["Type"]);

$title = html_entity_decode($row['Title']);
$poster = html_entity_decode($row['Poster_name']);
echo'{"id":"'.$row["ID"].'", "vimeoID":"'.$row["VimeoID"].'", "title":"'.$title.'" ,"client":"'.$row["Client"].'" , "production":"'.$row["Production"].'", "type":"'.$row["Type"].'", ';
            if($row["Type"] != "vimeo")
            {
                echo '"href":"'.http_build_query($data).'"';
            }
            else
            {
                echo '"href":"'.$row["Video_name"].'"';
            }
            echo ', "poster":"'.$poster.'"}';

            if($currentRow != $rowNumber)
            {
                echo ',';
            }
        }
        echo '];';

对不起,它有点乱,在记事本++中它看起来更好; / 我实际上是在一个脚本标签中输出它来制作一个对象而我看了json_encode并且真的不明白它是如何帮助我的,因为我不知道如何使用这么多变量,抱歉。

此外,这是使用来自该JSON对象的变量使用javascript制作标记后来自源代码:

<a production=" " client=" " title="O.S.T.R &amp;quot;Track #12&amp;quot;" href="http://player.vimeo.com/video/43886787?title=1&amp;amp;byline=1&amp;amp;portrait=1" rel="shadowbox" class="box">

3 个答案:

答案 0 :(得分:10)

(我无法理解这一点,所以它必须是一个答案。)

这里真正的问题是数据放入数据库的方式。我们来看看你给出的示例字符串:

$raw="O.S.T.R &amp;quot;Track #12&amp;quot;";
echo html_entity_decode($raw);
//   O.S.T.R &quot;Track #12&quot;
echo html_entity_decode(html_entity_decode($raw));
//   O.S.T.R "Track #12"

所以用户输入是 O.S.T.R“Track#12”

这里的关键概念是它应该如何存储在数据库中。因为那是实际数据。不要在数据库中存储修改后的版本。相反,请适当地转义数据,但是您需要输出它。

以下是我将用于以下几个示例的示例数据:

$title='O.S.T.R "Track #12"';
$description='A&B or A\B ??';

因此,当您在SQL语句中编写数据时,使用addslashes(或预处理语句,但我将在此处显示addslashes方法):

$sql="INSERT INTO xxx(title,description) VALUES('".addslashes($title)."','".addslashes($description)."')";
//   INSERT INTO xxx(title,description) VALUES('O.S.T.R \"Track #12\"','A&B or A\\B ??')

对于json编码,请使用json_encode:

$json=json_encode( array('title'=>$title,'description'=>$description) );
//   {"title":"O.S.T.R \"Track #12\"","description":"A&B or A\\B ??"}

要在csv中编码,请在日志文件中使用fputcsv:

$fp=fopen("my.csv","a");
fputcsv($fp, array($title,$description) );
fclose($fp);
//   "O.S.T.R ""Track #12""","A&B or A\B ??"

要输出为HTML,请使用htmlspecialchars()(或html_entity_encode()):

$html='<h3>'.htmlspecialchars($title).'</h3>';
$html.='<p>'.htmlspecialchars($description).'</p>';
//   <h3>O.S.T.R &quot;Track #12&quot;</h3><p>A&amp;B or A\B ??</p>

现在,也许我仍然没有说服你,你仍然真的想在你的数据库中存储HTML就绪数据,并且每次你想要将它用于其他任何事情时都要经过额外的步骤来取消HTML标记吗?在这种情况下,您的示例字符串应如下所示:

O.S.T.R &quot;Track #12&quot;

而你的字符串看起来像:

O.S.T.R &amp;quot;Track #12&amp;quot;

你看到了区别吗?第一个有html实体编码一次。拨打html_entity_decode()会正确解码。第二个已经编码了两次。它不再编码为html实体。我们将其称为双实体编码格式或简称DEEF。 PHP中没有deef_decode()函数,或者我听过的任何计算机语言,甚至没有比PHP更纯粹的函数。原因是因为没有人需要这个功能。

摘要:您的代码中存在写入其数据库的错误。您正在接收已编码实体的字符串,但在将它们写入数据库之前,您将再次对它们进行编码。

结论:回到上面给出的关键概念,您应该在将这些html实体写入数据库之前对其进行解码,而不是第二次对它们进行编码。但是,当您进行此更改时,请确保从数据库获取数据并将其放入HTML或XML的所有代码都知道它现在必须对实体进行编码。

答案 1 :(得分:3)

我不完全确定这里的问题是什么,但我想知道为什么你没有使用json_encode()来构建对象?

这将为您解决所有编码问题。

答案 2 :(得分:-1)

好吧,如果有人遇到同样的问题,并且自己也不会弄清楚这个废话,解决方法很简单,PHP函数html_entity_decode和htmlspecialchars_decode不会完全脱离特殊字符串,它只会剥离一个特殊字符串,如果你有两个特殊的字符,你需要运行这个函数两次...例如这个字符串:
O.S.T.R &amp;quot;Track #12&amp;quot;

需要条纹两次,首先是&amp;然后另一次剥去那些“-es。