簡體   English   中英

如何在樹枝模板中訪問 JSON 數據?

[英]How to access JSON data in a twig template?

我正在使用 Symfony2 並向 api 發出 php curl 請求。 我希望確保以正確的形式返回結果:作為json字符串(不是 php 對象或其他東西)。 返回的json字符串被 renderAPIResults() 使用,它使用 twig 來“渲染”一個JsonResponse 這可能嗎?

我可以在renderAPIResults “渲染”響應,還是需要返回一個JsonResponse並讓樹枝模板渲染它,從 apiAction() 調用?

是否有任何內置的 Symfony2 功能,其中如果將模板命名為results.json.twigresults.html.twig ,或者這種命名約定只是慣用的?

我已經能夠通過渲染得到的結果為results.html.twig Response()renderAPIResults()方法,但我只能夠console.log()從結果.js返回結果時文件一個JsonResponse() 嘗試以某種方式“渲染” JsonResponse時,我無法在results.json.twig模板中以任何形狀或形式解析這些結果。

     //DefaultController.php
     public function curlRestRequest($apiQueryString, $jsonDecode = FALSE, array $post_data = null, $service_url = null){

        if(!$service_url) {
            $service_url = 'http://website.com/rest';
        }

        $curl = curl_init($service_url.$apiQueryString);

        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);

        $curl_response = curl_exec($curl);

        if ($curl_response === false) {
            $info = curl_getinfo($curl);
            curl_close($curl);
            die('error occured during curl exec. Additioanl info: ' . var_export($info));
        }
        curl_close($curl);

        if($jsonDecode)
        {
            $curl_response = json_decode($curl_response);
        }

        return $curl_response;
    }

    public function renderAPIResults($data, $asObject = FALSE, $template)
    {
        if(!$template) {
            throw new Exception('Must provide a template name before rendering!');
        }

        if($asObject != TRUE) {
            // we want to cast to array since specified as OBJECT = FALSE, removing all instances of objects
            $dataArray = json_decode(json_encode($data), true);
            return $this->render($template, array('data' => $dataArray));
        } else { // Is JSON Decoded, if it is an object
            //just return json data, parse it in javascript instead of with template

            $response = new JsonResponse();
            $response->setData(array(
                'data' => $data
            ));
            return $response;
            //return $this->renderView($template, array('data' => $data));
            //or
            //$content = $this->render($template, array('data' => $data));
            //return new JsonResponse($content);
        }
    }

    public function apiAction($type, $query){
      $apiQueryString = '/search/' . $type . '?query=' . $query;

      //make a curl request
      $requestedResults = ($this->curlRestRequest($apiQueryString, TRUE));

      //return option three: (dont use any response object, and just pass, just pass curl-results directly)
      //note, currently, when set as true, its not rendered in the template, the template is not used
      $view = $this->renderAPIResults($requestedResults, TRUE, 'ApiBundle:API:results.json.twig');
      return $view;
    }

這是樹枝模板:

    //results.json.twig
    {{ dump(data) }}

基本上,我問:

我如何利用renderAPIResults()方法中的JsonResponse()以相同的方法呈現results.json.twig ,返回此呈現的模板,以便模板本身可以循環遍歷json結果?

我可以使用JsonResponse()以這種方式呈現模板嗎? 或者我必須在渲染時只使用Response()方法?

如果我不能使用JsonResponse來渲染,我可以使用它的母語直接在 twig 中解析結果嗎? {{ dump(results) }}還是我需要在腳本標簽中包含 javascript 並首先處理這些結果?


編輯:我想我找到了解決問題的方法。

當你使用 json_decode($string,TRUE) 時,如果它是一個深度嵌套的數組,那么嵌套的組件不會像我想象的那樣最終成為一個完美的嵌套數組,只有頂級的才會這樣。 這是 json_decode 或糟糕的 json 的自然副作用,還是我做錯了什么?

我認為這篇文章有助於闡明這一點。 json_decode/多維數組后訪問JSON數組

所以看起來我遇到的問題是 JSON 數據不完全干凈。

IE

    $requestedResults = ($this->curlRestRequest($apiQueryString, TRUE));
    print_r($requestedResults);
    //yields  Array
    (
        [category] => 
        [executionTime] => 759
        [facets] => 
        [resultCount] => 8
        [searchCount] => 0
        [searchInfo] => 
        [searchResults] => Array
            (
                [0] => Array
                    (
                        [description] => Gives instructions for 3 different in-class games.
                        [taxonomyDataSet] => {"course":[],"topic":[],"unit":[],"lesson":[],"subject":[],"curriculum":{"curriculumName":["Common Core State Standards - Math","Common Core State Standards - Math"],"curriculumCode":["CCSS.M.8.G.C.9","CCSS.M.7.G.B.6"],"curriculumDesc":["Solve real-world and mathematical problems involving area, volume and surface area of two- and three-dimensional objects composed of triangles, quadrilaterals, polygons, cubes, and right prisms.","Know the formulas for the volumes of cones, cylinders, and spheres and use them to solve real-world and mathematical problems."]}}
    [thumbnail] => slides/thumbnail.jpg
                            [title] => Game Suggestions for Volume
                        )            
        )

例如,“curriculumCode”無法訪問,或者無法通過twig訪問taxonomyDataSet中的任何內容,我不得不稍微按摩數據以清理它。

    $requestedResults = ($this->curlRestRequest($apiQueryString, TRUE));

        foreach ($requestedResults['searchResults'] as $resource) {
            $title = $resource["title"];
            $description = $resource["description"];
            $thumbnailUrl = $resource["thumbnails"]['url'];
            $taxonomyDataSet = json_decode($resource['taxonomyDataSet'],TRUE);
            $standard = $taxonomyDataSet['curriculum']['curriculumCode'];
            if(! file_exists($thumbnailUrl))
            {
                $thumbnailUrl = NULL;
            }

            $results[] = array($title,$description,$thumbnailUrl, $standard);
        }
    print_r($results);

    //yields
    Array
    (
    [0] => Array
        (
            [0] => Game Suggestions for Volume
            [1] => Gives instructions for 3 different in-class games.
            [2] => 
            [3] => Array
                (
                    [0] => CCSS.M.8.G.C.9
                    [1] => CCSS.M.7.G.B.6
                )

        ))

為什么我必須采取這個額外的步驟,沒有更好的方法來正確迭代 JSON 字符串,這樣就不會發生這種情況嗎?

我更喜歡將它保留為一個對象,然后在控制器return $requestedResults->searchResults中像這樣簡單地返回它,在那里我可以安全地在 TWIG 中迭代它而無需所有數據按摩。

編輯,好的,再次深入研究這個問題,我相信公司的 API 數據是罪魁禍首,結果的一個特定部分看起來是雙重 json_encoded,這就是為什么數據在我按摩之前無法訪問的原因。 是我,還是看起來這就是正在發生的事情?

考慮使用FOSRestBundle ,它將處理您的請求並“自動”返回正確的 JSON 響應。 配置基本用法很簡單,然后您只需遵循約定即可實現簡單有效的 REST API。

您可以使用Guzzle作為 API 客戶端來檢索數據。 您可以編寫一些客戶端類並提供實現一些邏輯的方法(每個資源的方法)。 然后在這些方法中,您只需使用,例如, $response = $guzzleClient->get($url, $options)並且在$reponse->json()您擁有可以在自己的 API 中處理和提供的所有數據回復。

您應該將該 API 客戶端注冊為服務並在自己的控制器中使用它來檢索數據,然后對其進行處理並從控制器的操作中返回預期結果。 然后您可以通過 FOSRestBundle+JMSSerializerBundle 處理它以進行 JSON 響應(您也可以返回 XML,這是使用允許的格式並使用提供的格式參數請求資源的問題 - 例如獲取/api/users.xml將返回 XML 文件,而/api/users.json將產生 JSON)。

這是一個廣泛的話題,幾乎不可能描述為了實現你想要的東西你必須做的所有事情,但我相信它會幫助你獲得正確的解決方案。

我不確定我是否理解這個問題,但讓我們繼續:

在我看來,您應該在將 API 結果發送到視圖之前對其進行處理,這意味着您應該將 JSON 字符串解析為 PHP 對象,創建一個數組,然后照常迭代 twig。

因此,集中精力開發一段代碼,將 JSON 字符串轉換為對象數組; 並且不要將邏輯傳遞給視圖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM