php - 通过json在php中递归调用
问题描述
我有这个 json 数据
$innerdata = json_decode('{
"sync_block": false,
"contacts": [{
"con_title": "",
"con_fName": "",
"con_lName": "",
"con_job_title": "",
"emails": [{
"email": "",
"type": "",
"primary": false,
"nest_uid": "1_1_1536657342_lyBhkbkDfG",
"checked": false
},
{
"email": "",
"type": "",
"primary": false,
"nest_uid": "1_1_1536657342_lyBhkbkDfGLp",
"checked": false
}],
"phones": [{
"phone": "",
"type": "",
"primary": false,
"nest_uid": "1_1_1536657342_CQPBBUBRZN",
"checked": false
}],
"nest_uid": "1_1_1536657342_fpTI2RF3XK",
"checked": false
}]
}');
然后我得到我需要找到的nest_uid
$uid='1_1_1536657342_lyBhkbkDfGLp';
我需要对 json 进行递归调用并返回其对象
nest_uid == $uid
在上面的 json 中,输出应该是
{
"email": "",
"type": "",
"primary": false,
"nest_uid": "1_1_1536657342_lyBhkbkDfGLp",
"checked": false
}
我尝试编写一个函数,但它没有按预期工作
function traverse($innerdata,$uid){
$res=$innerdata;
foreach($innerdata as $key=>$property)
{
if($key=='nest_uid'&& $property ==$uid)
{
break;
}
else if(is_array($property))
{
foreach($property as $innerproperty){
echo "1";
traverse($innerproperty,$uid);
}
}
}
return $res;
}
如果有人可以帮助我会很棒
解决方案
搜索者:
class Searcher
{
private $data;
private $uid;
private $result;
public function __construct($data, $uid)
{
$this->data = $data;
$this->uid = $uid;
}
private function search($data, $path)
{
foreach ($data as $k => $v) {
if (is_array($v) || is_object($v)) {
$subPath = $path;
$subPath[] = $k;
if ((is_array($v) && isset($v['nest_uid']) && $v['nest_uid'] === $this->uid)
|| (is_object($v) && isset($v->nest_uid) && $v->nest_uid === $this->uid)) {
$this->result[join('/', $subPath)] = $v;
}
$this->search($v, $subPath);
}
}
}
public function getResult()
{
if ($this->result === null) {
$this->result = [];
$this->search($this->data, []);
}
return $this->result;
}
}
演示代码:
$innerdata = json_decode('{
"sync_block": false,
"contacts": [{
"con_title": "",
"con_fName": "",
"con_lName": "",
"con_job_title": "",
"emails": [{
"email": "",
"type": "",
"primary": false,
"nest_uid": "1_1_1536657342_lyBhkbkDfG",
"checked": false
},
{
"email": "",
"type": "",
"primary": false,
"nest_uid": "1_1_1536657342_lyBhkbkDfGLp",
"checked": false
}],
"phones": [{
"phone": "",
"type": "",
"primary": false,
"nest_uid": "1_1_1536657342_CQPBBUBRZN",
"checked": false
},
{
"phone": "",
"type": "",
"primary": false,
"nest_uid": "1_1_1536657342_CQPBBUBRZN",
"checked": false
}],
"nest_uid": "1_1_1536657342_fpTI2RF3XK",
"checked": false
}]
}');
$searcher = new Searcher($innerdata, '1_1_1536657342_lyBhkbkDfG');
var_dump($searcher->getResult());
//with multi items
$searcher = new Searcher($innerdata, '1_1_1536657342_CQPBBUBRZN');
var_dump($searcher->getResult());
输出:
test_tmp.php:81:
array(1) {
'contacts/0/emails/0' =>
class stdClass#3 (5) {
public $email =>
string(0) ""
public $type =>
string(0) ""
public $primary =>
bool(false)
public $nest_uid =>
string(25) "1_1_1536657342_lyBhkbkDfG"
public $checked =>
bool(false)
}
}
test_tmp.php:85:
array(2) {
'contacts/0/phones/0' =>
class stdClass#5 (5) {
public $phone =>
string(0) ""
public $type =>
string(0) ""
public $primary =>
bool(false)
public $nest_uid =>
string(25) "1_1_1536657342_CQPBBUBRZN"
public $checked =>
bool(false)
}
'contacts/0/phones/1' =>
class stdClass#6 (5) {
public $phone =>
string(0) ""
public $type =>
string(0) ""
public $primary =>
bool(false)
public $nest_uid =>
string(25) "1_1_1536657342_CQPBBUBRZN"
public $checked =>
bool(false)
}
}
PS:如果要处理一级的另一种方法(例如:nest_uid
存在一级,只需替换上面类search
中的函数Searcher
):
private function search($data, $path)
{
foreach ($data as $k => $v) {
if ($k === 'nest_uid' && $v === $this->uid) {
$this->result[join('/', $path)] = $data;
}
if (is_array($v) || is_object($v)) {
$subPath = $path;
$subPath[] = $k;
$this->search($v, $subPath);
}
}
}
推荐阅读
- c# - 用于 C# 的 Selenium 中的警报阻止执行
- c++ - 为什么编译后会出现错误(c++ eigen)“error C2659: '=' : function as left operand”?
- haskell - 系统 T 组合语言的 Haskell 解释器
- java - 如何让我的机器人在没有更新的情况下发送消息?
- python - 在以日期时间为索引的python中使用interpolate.interp1d对数据进行插值
- c# - Json.NET 忽略字典中的空值
- flutter - 如何在解雇之前获得可解雇的拖动量 - Flutter
- c# - 有没有办法对函数参数使用'var'关键字?
- php - mysqli_query 不返回结果
- asp.net-mvc - Bootstrap 4 从右到左自定义文件输入