2013-01-24 25 views
13

可以在樹枝中解碼JSON嗎?谷歌搜索似乎沒有產生任何關於這一點。在Twig中解碼JSON不合理嗎?在Twig中解碼JSON


我想上的Symfony2的實體字段類型()訪問2實體屬性。

在2個以前做題(Symfony2 entity field type alternatives to "property" or "__toString()"?Symfony 2 Create a entity form field with 2 properties),其建議增加一個額外的方法將一個實體來檢索自定義字符串,而不是實體的屬性後,我想到的(也沒有)返回表示對象的JSON字符串實例。

某處在實體類:

/** 
* Return a JSON string representing this class. 
*/ 
public function getJson() 
{ 
    return json_encode(get_object_vars($this)); 
} 

並在窗體(類似):

$builder->add('categories', 'entity', array (
... 
'property' => 'json', 
... 
)); 

之後,我希望能json_decode它的樹枝...

{% for category in form.categories %} 
    {# json_decode() part is imaginary #} 
    {% set obj = category.vars.label|json_decode() %} 
{% endfor %} 
+0

爲什麼不'json_encode()在PHP'呢? –

+0

是的,我做'json_encode(get_object_vars($ this))'。問題是解碼,因爲它必須在Twig中,而不是PHP。 –

+0

我對Twig/Symfony2不熟悉,但是可以在您的操作中解碼它,並將其結果傳遞給您的Twig模板? – halfer

回答

26

這很容易,如果你extend twig

首先,創建一個類,將包含擴展:

<?php 

namespace Acme\DemoBundle\Twig\Extension; 

use Symfony\Component\DependencyInjection\ContainerInterface; 
use \Twig_Extension; 

class VarsExtension extends Twig_Extension 
{ 
    protected $container; 

    public function __construct(ContainerInterface $container) 
    { 
     $this->container = $container; 
    } 

    public function getName() 
    { 
     return 'some.extension'; 
    } 

    public function getFilters() { 
     return array(
      'json_decode' => new \Twig_Filter_Method($this, 'jsonDecode'), 
     ); 
    } 

    public function jsonDecode($str) { 
     return json_decode($str); 
    } 
} 

然後,註冊該類在services.xml文件:

<service id="some_id" class="Acme\DemoBundle\Twig\Extension\VarsExtension"> 
     <tag name="twig.extension" /> 
     <argument type="service" id="service_container" /> 
</service> 

然後,使用它在你的樹枝模板:

{% set obj = form_label(category) | json_decode %} 
+0

不應該在'getFilters()'裏面把''json_encode''變成''json_decode''嗎? – cheesemacfly

+0

確實如此,我已經更新了答案。乾杯! – Xocoatzin

+2

萬一有人找Services.yml設置:'acme_demo.twig.extension.vars_extension: 類:ACME \ DemoBundle \嫩枝\延期\ VarsExtension 參數:[@service_container] 標籤: - {名稱:「枝杈.extension'}' – HBK

3

我想出了一個讓我的JSON的方法,我想我會在這裏分享它,以防萬一它的用處t給別人。

所以在我的情況下,我可能有10個記錄(佈局)從MySQL數據庫返回並且每行都有一個名爲屬性的字段,這是一個JSON字符串。所以,我可以輕鬆地拉出記錄,並將它們發送到模板,像這樣:

echo $twig->render('template.html.twig', array(
     "layouts" => $layouts, 
)); 

到目前爲止好,但是當我在樹枝做我的{%佈局在佈局%}有沒有辦法因爲它們仍然是json字符串,所以需要到屬性字段項目。

所以之前我通過$佈局,以樹枝模板,我做了以下內容:

foreach($layouts as $i => $v) 
{ 
     $layouts[$i]->decoded = json_decode($v->getProperties()); 
} 

做這個香港專業教育學院創建的變量在我的對象內的蒼蠅叫「解碼」它包含了JSON解碼對象。

所以現在我的模板,我可以通過{{layout.decoded.whatever}}

訪問我的JSON的項目,這可能是一個有點哈克,而不是每個人一個很好的解決方案的想法。我爲我工作得很好,頭頂上的開銷很少,意味着我不需要在擴展枝條的時候就像在做模板之前的工作一樣。

2

替代以上所有。
我不知道這是否是最佳解決方案,但它作品

1)創建一個幫助函數寄存器它的功能。

<?php 
function twig_json_decode($json) 
{ 
    return json_decode($json, true); 
} 


2)在樹枝文件使用此功能。

{% set res = twig_json_decode(json) %} 
# above will return an array which can be iterated 

{% for r is res %} 
    {{ r }} 
{% endfor %} 
2

爲Symfony2.8或Symfony3更新代碼:

<?php 

namespace Acme\DemoBundle\Twig\Extension; 

use Symfony\Component\DependencyInjection\ContainerInterface; 
use \Twig_Extension; 

class VarsExtension extends Twig_Extension 
{ 
    protected $container; 

    public function __construct(ContainerInterface $container) 
    { 
     $this->container = $container; 
    } 

    public function getName() 
    { 
     return 'some.extension'; 
    } 

    // Note: If you want to use it as {{ json_decode(var) }} instead of 
    // {{ var|json_decode }} please use getFunctions() and 
    // new \Twig_SimpleFunction('json_decode', 'json_decode') 
    public function getFilters() { 
     return [ 
      // Note that we map php json_decode function to 
      // extension filter of the same name 
      new \Twig_SimpleFilter('json_decode', 'json_decode'), 
     ]; 
    } 
} 
0

在我來說,我已經在我的實體有一個JsonArray然後我在實體已經添加了Methode

<?php 
namespace ACME\DefaultBundle\Entity; 
/*...*/  
public function getDecodedPath() 
{ 
    return json_decode($this->path); 
} 
-1

對於Symfony 3.1,如official doc所述,有一個助手用於此目的:return $this->json()

/** 
* @Route("/", name="homepage") 
* @Method({"GET","POST"}) 
*/ 
public function indexAction() 
{ 
    $person = new Person(); 
    $form = $this->createForm(PersonType::class, $person,[ 
     'action'=>$this->generateUrl('homepage'), 
     'method'=>'POST' 
    ]); 
    $form->handleRequest($request); 
    if($form->isSubmitted() && $form->isValid()){ 
     return $this->json([ 
      'name'=>$person->getName(), 
      'age'=>$person->getAge() 
     ]); 
    } 
    return $this->render('default/index.html.twig',['form'=>$form->createView()]); 
} 

輸出是這樣的:

{"name":"john","age":39} 
+0

對於down -voter:你會不會詳細說明倒票? –

0

這是一個老問題,但我加入我的解決方案備案...只要有SimpleFunction延伸的樹枝:

// Return a string of separated values from a JSON string 
// Can optionally specify a separator. If none provided, ", " is used. 
$function = new Twig_SimpleFunction('json_to_list', function($json, $separator = ", ") 
{ 
    $result = ""; 
    $array = json_decode($json, true); 
    foreach ($array as $item) 
    { 
     if ($result != "") { $result .= $separator; }   
     $result .= $item; 
    } 
    return $result; 
}); 
$twig->addFunction($function); 

用法:

在調用枝條渲染之前,將a_json_variable設置爲字符串'[「1」,「2」,「3」,「4」,「5」]''。

嫩枝模板:

The values are: {{ json_to_list(a_json_variable) }} 

會產生

The values are: 1, 2, 3, 4, 5