[英]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.twig
與results.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.