1

We're working with lots of json data and trying to define via strings variable what parts of it to use.

So i'm trying to convert a string to an object path to an items content.

This works...

<?php 
$pmdd_ds_json_obj = json_decode($pmdd_ds_json_data);
echo $pmdd_ds_json_obj[0]->title->rendered; 
// shows "Wisconsin Investment Board"
?>

but i can't seem to get this to load the same as above.

$num = 0;
$root =  "pmdd_ds_json_obj[$num]->";
$content = "title->rendered"
$obj_content = ${$root.$content};

// tried other approached too.
echo $root.$content;
echo ${$root.$content};
echo ${"$root.$content"};

Is what i'm doing even possible? Tried a lot of variations and need a fresh set of eyes!

json data

[{
    "date": "2019-07-04T10:21:15",
    "title": {
        "rendered": "Wisconsin Investment Board"
    },
    "_links": {
        "self": [{
            "href": "https:\/\/refi.global\/europe\/wp-json\/wp\/v2\/posts\/309891"
        }]
    }
}]

1 Answer 1

1

Variable variables won't process the array key, or arrow operators, like you've tried. You could do what you're trying to do by using eval(), but don't :P

However, json_decode accepts a flag to return an associative array rather than stdClass objects. https://www.php.net/manual/en/function.json-decode.php

$foo = json_decode($json, true);

Once you have that, you could get the value you want by using a function to resolve an array value by dot notation, which can be stored as a variable. See this answer: https://stackoverflow.com/a/14706302/2286736

<?php

$json = '[{
    "date": "2019-07-04T10:21:15",
    "title": {
        "rendered": "Wisconsin Investment Board"
    }
}]';

// decode as associative array
$pmdd_ds_json_obj = json_decode($json, true);

/**
 * @link https://stackoverflow.com/a/14706302/2286736
 */
function resolve(array $a, $path, $default = null) {
    $current = $a;
    $p = strtok($path, '.');

    while ($p !== false) {
        if (!isset($current[$p])) {
            return $default;
        }
        $current = $current[$p];
        $p = strtok('.');
    }

    return $current;
}

// key variable
$key = '0.title.rendered';

// value can be resolved by the dot notation path
$value = resolve($pmdd_ds_json_obj, $key);
var_dump($value); // Wisconsin Investment Board

Additional changes to the resolve() function to allow it to accept objects as well:

$json = '[{
    "date": "2019-07-04T10:21:15",
    "title": {
        "rendered": "Wisconsin Investment Board"
    },
    "_links": {
        "self": [{
            "href": "https:\/\/refi.global\/europe\/wp-json\/wp\/v2\/posts\/309891"
        }]
    }
}]';

// decode as normal (with stdClass)
$pmdd_ds_json_obj = json_decode($json);

function resolve($a, $path, $default = null) {
    $current = $a;
    $p = strtok($path, '.');

    while ($p !== false) {
        if (
            (is_array($current) && !isset($current[$p]))
            || (is_object($current) && !isset($current->$p))
        ) {
            return $default;
        }
        $current = is_array($current) ? $current[$p] : $current->$p;
        $p = strtok('.');
    }

    return $current;
}

// key variable
$key = '0._links.self.0.href';

// value can be resolved by the dot notation path
$value = resolve($pmdd_ds_json_obj, $key);
Sign up to request clarification or add additional context in comments.

2 Comments

thanks Ben. I did see this but wanted to stick to objects. I've tested this and it doesn't seem to do arrays in arrays.? ie '0._links.0.self.href' is that right?
In the case of your updated JSON, it would be 0._links.self.0.href ('self' is the array, not 'links'). I've updated the answer with some amends to the resolve() function to allow it to accept objects as well, so you don't need to use the assoc flag on json_decode() if you don't want to :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.