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

时间:2017-12-29 16:30:50

标签: php symfony twig

我有一个MySQL数据库,其中包含一些使用ckeditor创建的内容。文本存储方式与此<p><strong>L’automatisation des systèmes dans le monde一样,因此使用HTML实体。

使用Twig,在Symfony项目中,当我想显示我的数据时,我会使用此字段{{ article.mytext|raw}},但它会显示<p><strong>L&rsquo;automatisation des syst&egrave;mes dans le monde,因此它没有完全解码和解释......

使用PHP我没有问题,而html_entity_decode($mytext);可以完美地完成工作。

你能帮帮我吗?有什么问题?

根据要求,更多代码: 在MySQL的utf8_general_ci列“vTexte”中     &lt;p&gt;&lt;strong&gt;L&amp;rsquo;automatisation des syst&amp;egrave;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 %}

有了它,它显示:     <p><strong>L&rsquo;automatisation des syst&egrave;mes dans le monde

我希望:     

L'automatisationdessystèmesdansle monde

3 个答案:

答案 0 :(得分:0)

您必须将autoescape设置为false:

看那里:https://twig.symfony.com/doc/2.x/tags/autoescape.html

{% autoescape false %}
    {{ html_var }}
{% endautoescape %}

答案 1 :(得分:0)

小心控制编码。

您遇到的问题是最简单的噩梦形式,即字符编码。处理编码问题的规则一是始终控制编码。在您的情况下,此HTML应该真正存储在数据库中未编码,只允许使用twig raw输出过滤器。

如果您知道HTML是否需要解码,请考虑其影响。例如,如果有人打算在文本中显示<&lt;),并且html 不是编码的,那么应用html_entity_decode会将编码的 <转换为真实的,并打破HTML。 (浏览器会认为你正在开始新的TAG)。

表单提交html

我猜你应用程序的其他地方,有些表单允许人们提交HTML。 HTML表单在发布之前对数据进行编码,PHP $_POST处理通常会自动将htmlentities应用于已发布的字段。

无论您的应用程序处理存储此类已发布的HTML或添加/更改这些实体的任何方法,都应使用html_entity_decode确保将其存储为原始html。

这样,您始终知道HTML存储在您的数据库中的状态恰好是需要在页面上呈现的状态。如果由于某种原因需要在某处再次对其进行编码和解码,那么您并不希望某些内容不会被双重解码。 (或者在您的情况下,错过解码步骤并吐出原始HTML)。

在树枝中渲染HTML

无论如何,您需要将内容传递到您的树枝,通过raw过滤器,以及需要放在页面上的确切状态。虽然这个可以在树枝上完成,或者用树枝函数完成,但这确实应该在Controller中完成。

考虑这个数据传播的路径:

  1. 表单(原始HTML)
  2. PHP POST(编码HTML)
  3. DB(编码HTML)
  4. SELECT Query
  5. PHP控制器(编码的HTML)
  6. Twig
  7. 呈现HTML
  8. 越早获得正确状态的数据越好。这样做可以使数据更易于使用,降低性能影响,并在以后的步骤中防止代码重复。 (如果你想在其他控制器或Twig模板中使用这个html会发生什么?代码重复。)Hense,我的第一个建议是干净地把它放到数据库中。

    如果干净的数据不是一个选项......

    清理控制器中的数据,甚至可以使用实体中的静态功能。

    唯一的其他clean- ish 处理方法是在将html传递给Twig之前循环并解码html。不过这样做,或者稍后在你正在做的Tiwg模板中,你冒着我前面提到的双重解码的风险。

    Veille

    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。只需确保您只解码ONCE,任何可以添加或编辑这些实体的方法都会存储HTML 未编码 。这是关键。未编码的数据。

答案 2 :(得分:0)

{{html_var | convert_encoding('UTF-8','HTML-ENTITIES')}}