使用PHP的白色过滤器JSON
我从后端收到一个API响应,并希望通过JS将其转发到客户端(浏览器)。 但是不应该有来自服务器的洞响应 一个JSON可能看起来像:使用PHP的白色过滤器JSON,php,json,filtering,Php,Json,Filtering,我从后端收到一个API响应,并希望通过JS将其转发到客户端(浏览器)。 但是不应该有来自服务器的洞响应 一个JSON可能看起来像: "{\"total\":6,\"sort\":{\"field\":\"created_at\",\"order\":\"desc\"},\"constraints\": [],\"pagination\": {\"current\":1,\"previous\":null,\"next\":null,\"per_page\":25,\"pages\"
"{\"total\":6,\"sort\":{\"field\":\"created_at\",\"order\":\"desc\"},\"constraints\": [],\"pagination\": {\"current\":1,\"previous\":null,\"next\":null,\"per_page\":25,\"pages\":1,\"count\":6},\"response\":[{\"id\":10,\"name\":\"Prof. Dr. Dr. h. c.\",\"people_count\":2,\"allowed_actions\":{\"destroy\":false}},{\"id\":9,\"name\":\"Dr. h. c.\",\"people_count\":1,\"allowed_actions\":{\"destroy\":false}},{\"id\":8,\"name\":\"Dr. Dr.\",\"people_count\":0,\"allowed_actions\":{\"destroy\":true}},{\"id\":7,\"name\":\"Prof. Dr.\",\"people_count\":0,\"allowed_actions\":{\"destroy\":true}},{\"id\":6,\"name\":\"Prof.\",\"people_count\":4,\"allowed_actions\":{\"destroy\":false}},{\"id\":5,\"name\":\"Dr.\",\"people_count\":110,\"allowed_actions\":{\"destroy\":false}}],\"statuscode\":200}"
为了过滤这些,我开始编写一个whitelister。他在表单数组(“statuscode”、“response.name”、“response.id”、“total”)中获取json+白名单的漏洞。
现在,他应该遍历这个JSON递归并返回一个具有相同结构但删除了所有其他节点的JSON
这是我目前的状态:
public function filter($response,$whitelist,$depth = 0) {
$filteredResponse = "";
foreach (json_decode($response,true) as $key => $value) {
foreach ($whitelist as $item) {
$items = explode(".",$item);
foreach($items as $it) {
if($it === $key && strlen($it)>0) {
if(is_array($value)) {
for($i=1;$i<count($items);$i++) {
$str .= $it.".";
}
$filteredResponse[$it] = $this->filter(json_encode($value),array($str),$depth+1);
}
else $filteredResponse[$key] = $value;
}
}
}
}
return json_encode($filteredResponse);
}
公共函数过滤器($response,$whitelist,$depth=0){
$filteredResponse=“”;
foreach(json_解码($response,true)为$key=>$value){
foreach($项目的白名单){
$items=分解(“.”,$item);
foreach($it形式的项目){
如果($it==$key&&strlen($it)>0){
if(是_数组($value)){
对于($i=1;$ifilter(json_encode($value)、数组($str),$depth+1);
}
else$filteredResponse[$key]=$value;
}
}
}
}
返回json_encode($filteredResponse);
}
我现在的结果是{“总计”:6,“响应”:“\”\”,“状态码”:200}。
有人能帮我吗?试试这个
<?php
$str = "{\"total\":6,\"sort\":{\"field\":\"created_at\",\"order\":\"desc\"},\"constraints\": [],\"pagination\": {\"current\":1,\"previous\":null,\"next\":null,\"per_page\":25,\"pages\":1,\"count\":6},\"response\":[{\"id\":10,\"name\":\"Prof. Dr. Dr. h. c.\",\"people_count\":2,\"allowed_actions\":{\"destroy\":false}},{\"id\":9,\"name\":\"Dr. h. c.\",\"people_count\":1,\"allowed_actions\":{\"destroy\":false}},{\"id\":8,\"name\":\"Dr. Dr.\",\"people_count\":0,\"allowed_actions\":{\"destroy\":true}},{\"id\":7,\"name\":\"Prof. Dr.\",\"people_count\":0,\"allowed_actions\":{\"destroy\":true}},{\"id\":6,\"name\":\"Prof.\",\"people_count\":4,\"allowed_actions\":{\"destroy\":false}},{\"id\":5,\"name\":\"Dr.\",\"people_count\":110,\"allowed_actions\":{\"destroy\":false}}],\"statuscode\":200}";
$arr = json_decode($str, true);
$arr_new = array();
$arr_new['total'] = $arr['total'];
$arr_new['statuscode'] = $arr['statuscode'];
foreach($arr['response'] as $arr_response)
{
$arr_new['response_id'][] = $arr_response['id'];
$arr_new['response_name'][] = $arr_response['name'];
}
print_r($arr_new);
?>
这是一个工作版本,它解决了我的问题:
public function filter($response,$whiteList,$depth = 0) {
$filteredResponse = $response;
foreach ($filteredResponse as $key => $value) {
$isBlackListed = true;
foreach ($whiteList as $whiteItem) {
$whiteTokens = explode(".", $whiteItem);
if($depth >= count($whiteTokens))
continue;
if($key !== $whiteTokens[$depth])
continue;
else {
if(is_array($value)) {
$isBlackListed = false;
if(!$this->is_assoc($value)) {
$i = 0;
foreach($value as $element) {
$filteredResponse[$key][$i] = $this->filter($element, $whiteList, $depth+1);
$i++;
}
} else {
if(count($whiteTokens) != $depth+1)
$filteredResponse[$key] = $this->filter($value, $whiteList, $depth+1);
}
} else {
$isBlackListed = false;
}
}
}
if($isBlackListed)
unset($filteredResponse[$key]);
$isBlackListed = true;
}
return $filteredResponse;
}
private function is_assoc($array) {
return (bool)count(array_filter(array_keys($array), 'is_string'));
}
您的JSON是一个包含更多JSON的字符串?我得到了如上所示的字符串。使用JSON_decode()和JSON_encode,我得到了我的JSON或返回了字符串。@lvaroG.Vicario没有它的常规JSON(Firefox解析它很好)我建议编写一个已经接受解码数组的过滤器函数,并将结果重新编码为json,这样它就只关心php数组,而不关心其他数组JSON@birdspider-问题中所显示的内容没有通过,这就是我提出问题的原因。尽管这可能与问题无关:我认为这都是关于如何深入循环的问题ed Array,而不是JSON。感谢您的快速帮助。但问题是,此筛选器通常应适用于此表单中的所有JSON以及每个白名单输入。因此,我必须遍历输入并递归工作。这是我的大问题…我无法实现这一点:(你想得到什么?例如,我有上面的旧响应:我的白过滤器是数组(“statuscode”、“response.id”、“response.name”)。我想要这个输出:希望我的问题现在更清楚了?我又添加了一个答案,现在试试这个问题更复杂了……:(再次感谢。但我认为我的问题还不够清楚。您的解决方案工作得很好-但它是硬编码的。我需要一个函数调用,如filter($json、$whitelist,…)和$whitelist=[“total”、“statuscode”、“response.name”、“response.id”];但它还应该与[“sort”、“response.name”、“response.people\u count”]一起工作;或完全不同的JSON。这就是为什么我使用foreach($whitelist as$item){$items=explode(“.”,$item);…}
<?php
$str = "{\"total\":6,\"sort\":{\"field\":\"created_at\",\"order\":\"desc\"},\"constraints\": [],\"pagination\": {\"current\":1,\"previous\":null,\"next\":null,\"per_page\":25,\"pages\":1,\"count\":6},\"response\":[{\"id\":10,\"name\":\"Prof. Dr. Dr. h. c.\",\"people_count\":2,\"allowed_actions\":{\"destroy\":false}},{\"id\":9,\"name\":\"Dr. h. c.\",\"people_count\":1,\"allowed_actions\":{\"destroy\":false}},{\"id\":8,\"name\":\"Dr. Dr.\",\"people_count\":0,\"allowed_actions\":{\"destroy\":true}},{\"id\":7,\"name\":\"Prof. Dr.\",\"people_count\":0,\"allowed_actions\":{\"destroy\":true}},{\"id\":6,\"name\":\"Prof.\",\"people_count\":4,\"allowed_actions\":{\"destroy\":false}},{\"id\":5,\"name\":\"Dr.\",\"people_count\":110,\"allowed_actions\":{\"destroy\":false}}],\"statuscode\":200}";
$arr = json_decode($str, true);
$arr_new = array();
$arr_new['total'] = $arr['total'];
$arr_new['statuscode'] = $arr['statuscode'];
foreach($arr['response'] as $arr_response)
{
$arr_temp = array();
$arr_temp['id'] = $arr_response['id'];
$arr_temp['name'] = $arr_response['name'];
$arr_new['response'][] = $arr_temp;
}
print_r($arr_new);
echo json_encode($arr_new);
?>
Array
(
[total] => 6
[statuscode] => 200
[response] => Array
(
[0] => Array
(
[id] => 10
[name] => Prof. Dr. Dr. h. c.
)
[1] => Array
(
[id] => 9
[name] => Dr. h. c.
)
[2] => Array
(
[id] => 8
[name] => Dr. Dr.
)
[3] => Array
(
[id] => 7
[name] => Prof. Dr.
)
[4] => Array
(
[id] => 6
[name] => Prof.
)
[5] => Array
(
[id] => 5
[name] => Dr.
)
)
)
{"total":6,"statuscode":200,"response":[{"id":10,"name":"Prof. Dr. Dr. h. c."},{"id":9,"name":"Dr. h. c."},{"id":8,"name":"Dr. Dr."},{"id":7,"name":"Prof. Dr."},{"id":6,"name":"Prof."},{"id":5,"name":"Dr."}]}
public function filter($response,$whiteList,$depth = 0) {
$filteredResponse = $response;
foreach ($filteredResponse as $key => $value) {
$isBlackListed = true;
foreach ($whiteList as $whiteItem) {
$whiteTokens = explode(".", $whiteItem);
if($depth >= count($whiteTokens))
continue;
if($key !== $whiteTokens[$depth])
continue;
else {
if(is_array($value)) {
$isBlackListed = false;
if(!$this->is_assoc($value)) {
$i = 0;
foreach($value as $element) {
$filteredResponse[$key][$i] = $this->filter($element, $whiteList, $depth+1);
$i++;
}
} else {
if(count($whiteTokens) != $depth+1)
$filteredResponse[$key] = $this->filter($value, $whiteList, $depth+1);
}
} else {
$isBlackListed = false;
}
}
}
if($isBlackListed)
unset($filteredResponse[$key]);
$isBlackListed = true;
}
return $filteredResponse;
}
private function is_assoc($array) {
return (bool)count(array_filter(array_keys($array), 'is_string'));
}