提问者:小点点

用Twig(在Symfony中)解码存储在MySQL中的HTML实体


我有一个MySQL数据库,其中有些内容是用Ckeditor创建的。文本存储方式如下:

l’automatisation des systemè;mes dans le monde,HTML实体也是如此。

对于Twig,在Symfony项目中,当我要显示数据时,我对此字段使用{{article.myTextraw}}但它显示

L’Automatisation des System&eGrave;Mes dans le Monde所以它没有完全解码和解释...

使用PHP我没有问题,HTML_Entity_Decode($mytext);可以很好地完成这项工作。

你能帮帮我吗?怎么啦?

根据需要,更多代码:在MySQL中的utf8_general_ci列“vtexte”

L’Automatisation des SystemÈ;MES dans le Monde

在symfony中的我的控件中:

namespace MU\CoreBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use MU\CoreBundle\Entity\Veille;

class CoreController extends Controller
{

public function actufreeAction()
{

  $repository = $this
    ->getDoctrine()
    ->getManager()
    ->getRepository('MUCoreBundle:Veille')
  ;

  $listactufree = $repository->findBy(
          array('vStatus' => '4'), // Critere
          array('vDatePublished' => 'desc'),        // Tri
          5,                              // Limite
          0                               // Offset
        );  



    $content = $this->get('templating')->render('MUCoreBundle::news.html.twig', array(
  'listactufree'  => $listactufree,
));
    return new Response($content);
}

}

在我的Twig文件news.html.Twig中

{% for veille in listactufree %}

    {{ veille.vTexte | raw }}

{% endfor %}

这样,它就显示了:

L’Automatisation des systemè;mes dans le monde

我想要:

世界系统自动化


共1个答案

匿名用户

您遇到的问题是最简单的形式的噩梦,即字符编码。处理编码问题的第一条规则是始终控制编码。在您的情况下,这个HTML实际上应该未编码地存储在DB中,允许使用twigraw输出过滤器。

如果您不知道HTML是否需要解码,请考虑其含义。例如,如果有人打算在文本中显示<(<),而html没有被编码,那么应用HTML_Entity_Decode将把编码的<转换为真实的,并中断html。(浏览器会认为您正在启动一个新标记)。

我猜在应用程序的其他地方,有允许用户提交HTML的表单。HTML表单在发布前对数据进行编码,PHP$_post处理通常自动将HTMLEntities应用到发布的字段上。

无论您的应用程序使用什么方法来处理这些发布的HTML的存储,或者添加/更改这些实体,都应该使用HTML_Entity_Decode来确保将其存储为原始HTML。

这样,您就会知道HTML存储在您的数据库中的状态正是它需要呈现在页面上的状态。如果由于某种原因需要在某个地方重新编码和解码,您就不会希望某些内容不会被双重解码。(或者就像您的情况一样,缺少解码步骤并输出原始HTML)。

您需要通过raw筛选器将这些内容放到您的twig中,使其处于需要放在页面上的确切状态。虽然这可以在twig中完成,或者使用twig函数完成,但这确实应该在控制器中完成。

请考虑此数据正在传输路径:

  1. 表单(原始HTML)
  2. PHP POST(编码的HTML)
  3. 数据库(编码的HTML)
  4. 选择查询
  5. PHP控制器(编码HTML)
  6. 小枝
  7. 呈现的HTML

越早能够获得处于正确状态的数据越好。这样做可以使数据更容易处理,降低性能影响,并防止在这些步骤的后面出现代码重复。(如果要在其他控制器或Twig模板中使用此html会发生什么?代码重复。)Hense,我的第一个建议是把它干净利落地放进数据库。

如果清理数据不是一个选项...

处理这个问题的另一个简单方法是在将html传递给Twig之前循环并解码html。但是,以这种方式执行,或者稍后在Tiwg模板中执行当前的操作,您将冒着我前面提到的双重解码的风险。

Class Veille
{

    . . .

    public static function decodeArray(?array $vielleList): ?array
    {
        foreach ($vielleList as $vielle) {
            if (!$vielle instanceof self) {
                continue;
            }

            $vielle->setVText(html_entity_decode($vielle->getVText()));
        }

        return $vielleList;
    }

    public function getVText(): ?string
    {
        return htmlentities("<h3>Encoded HTML Test</h3>Good data &gt; parsing bad data.");
    }

    public function setVText(?string $text): void
    {

    }
}
$listactufree = $repository->findBy(
    array('vStatus' => '4'), // Critere
    array('vDatePublished' => 'desc'),        // Tri
    5,                              // Limite
    0                               // Offset
);


$listactufree = Veille::decodeArray($listactufree);
{% for veille in listactufree %}

    {{ veille.vTexte|raw }}

{% endfor %}

decodearray方法的内容插入到一个命令中,并运行该命令以及persist/flush,将存储所有实体的解码HTML。只要确保您只解码一次,并且任何可以添加或编辑这些实体的方法都存储未编码的HTML。这才是关键。未编码的数据。