首页 > 解决方案 > 通过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;  

  }

如果有人可以帮助我会很棒

标签: phprecursion

解决方案


搜索者:

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);
        }
    }
}

推荐阅读