user8054217
user8054217

Reputation:

Fetch JSON data by specific value

I'm struggling in making this work and I hope someone can give me a push in the right direction. I'm creating a dashboard which fetches data from multiple sources: Google Analytics, Google Trends and so on. With this being a proof of concept, I'm trying to emulate the different sources by using a JSON file with the following structure:

{
  "data":
  [
    {
      "source":"google analytics",
      "data":
      [
        {
          "month":"jan",
          "visitors":"593"
        },
        {
          ...
        }
      ]
    },
    {
      "source":"google trends",
      "keywords":
      [
        {
          "value":"keyword 1",
          "data":
          [
            {
              "month":"dec",
              "popularity":"10"
            },
            {
              ...
            }
          ]
        },
        {
          "value":"keyword 2",
          "data": ...
        }
      ]
    }
  ]
}

Next I have a dropdown list with keywords from a MySQL database query. When a user selects a keyword from that list, I want the data from the JSON file that matches that specific keyword to show.

For example, when a user selects "keyword 1" from the dropdown list, the values "Dec" and "100" need to be fetched, which will then be used by Chart.js

Right now I have the following piece of code:

$dataFile = json_decode(file_get_contents($src));
$data = $dataFile->data[1]->keywords[0]; // Google Trends

foreach ($data->results as $result) {
  echo "<li><p>" . $result->month . "</p></li>";
  echo "<li><p>" . $result->popularity . "</p></li>";
}

This does show the correct data, being the months and popularity scores, but obviously only for the keyword defined by using the array value. How can I make this show data for the selected keyword (which is posted via GET)?

What I'm trying to do is:

$dataFile = json_decode(file_get_contents($src));
$data = $dataFile->data["google trends"]->keywords[$selectedKeyword];

foreach ($data->results as $result) {
  echo "<li><p>" . $result->month . "</p></li>";
  echo "<li><p>" . $result->popularity . "</p></li>";
}

I'm aware of the second parameter of json_decode which makes it an associative array, but I'm not sure how I can use it to accomplish what I'm trying to do..

This is currently the result of $data:

object(stdClass)#10 (2) {
  ["value"]=>
  string(10) "keyword 1"
  ["data"]=>
  array(7) {
    [0]=>
    object(stdClass)#11 (2) {
      ["month"]=>
      string(3) "dec"
      ["popularity"]=>
      string(2) "10"
    }
    [1]=>
    object(stdClass)#12 (2) {
      ["month"]=>
      string(3) "jan"
      ["popularity"]=>
      string(1) "5"
    }
    [2]=>
    object(stdClass)#13 (2) {
      ["month"]=>
      string(3) "feb"
      ["popularity"]=>
      string(1) "8"
    }
    [3]=>
    object(stdClass)#14 (2) {
      ["month"]=>
      string(3) "mar"
      ["popularity"]=>
      string(1) "5"
    }
    [4]=>
    object(stdClass)#15 (2) {
      ["month"]=>
      string(3) "apr"
      ["popularity"]=>
      string(2) "10"
    }
    [5]=>
    object(stdClass)#16 (2) {
      ["month"]=>
      string(3) "mei"
      ["popularity"]=>
      string(2) "20"
    }
    [6]=>
    object(stdClass)#17 (2) {
      ["month"]=>
      string(3) "jun"
      ["popularity"]=>
      string(2) "10"
    }
  }
}

Upvotes: 1

Views: 229

Answers (2)

Akshay Hegde
Akshay Hegde

Reputation: 16997

You can't access object that way with given input json file, what you can do is as follows

$selected_keyword = 'keyword 1';

$dataFile = json_decode(file_get_contents($src));


foreach($dataFile->data as $trend)
{
    /* Source you are looking */
    if($trend->source == 'google trends')
    {
        foreach($trend->keywords as $keyword)
        {
            /* Keyword which I am looking for */
            if($keyword->value == $selected_keyword)
            {
                foreach ($keyword->data as $result) 
                {
                    echo "<li><p>" . $result->month . "</p></li>";
                    echo "<li><p>" . $result->popularity . "</p></li>";
                }
            }
        }
    }

}

Here is test results

Input - t.json

akshay@db-3325:/tmp$ cat t.json 
{
  "data":
  [
    {
      "source":"google analytics",
      "data":
      [
        {
          "month":"jan",
          "visitors":"593"
        }

      ]
    },
    {
      "source":"google trends",
      "keywords":
      [
        {
          "value":"keyword 1",
          "data":
          [
            {
              "month":"dec",
              "popularity":"100"
            }
          ]
        },
        {
          "value":"keyword 2",
          "data": []
        }
      ]
    }
  ]
}

Script - t.php

akshay@db-3325:/tmp$ cat t.php 
<?php

$selected_keyword = 'keyword 1';

$dataFile = json_decode(file_get_contents('t.json'));

/* Your input */
print_r($dataFile);

foreach($dataFile->data as $trend)
{
    /* Source you are looking */
    if($trend->source == 'google trends')
    {
        foreach($trend->keywords as $keyword)
        {
            if($keyword->value == $selected_keyword)
            {
                foreach ($keyword->data as $result) 
                {
                    /* Your output */
                    echo "<li><p>" . $result->month . "</p></li>";
                    echo "<li><p>" . $result->popularity . "</p></li>";
                }
            }
        }
    }

}
?>

Execution & Output

akshay@db-3325:/tmp$ php t.php 
stdClass Object
(
    [data] => Array
        (
            [0] => stdClass Object
                (
                    [source] => google analytics
                    [data] => Array
                        (
                            [0] => stdClass Object
                                (
                                    [month] => jan
                                    [visitors] => 593
                                )

                        )

                )

            [1] => stdClass Object
                (
                    [source] => google trends
                    [keywords] => Array
                        (
                            [0] => stdClass Object
                                (
                                    [value] => keyword 1
                                    [data] => Array
                                        (
                                            [0] => stdClass Object
                                                (
                                                    [month] => dec
                                                    [popularity] => 100
                                                )

                                        )

                                )

                            [1] => stdClass Object
                                (
                                    [value] => keyword 2
                                    [data] => Array
                                        (
                                        )

                                )

                        )

                )

        )

)
<li><p>dec</p></li><li><p>100</p></li>

Upvotes: 1

D Lowther
D Lowther

Reputation: 1619

Your initial example seems to ignore that all of your keyword results are subgrouped under a data object key. You have a few collections in the JSON object that need to be iterated to access the next level. The example below is one way to dig into a data object dynamically

$dataFile = json_decode(file_get_contents($src));

$source = getSource($dataFile->data, $dataSource);

foreach ($source->keywords as $group) {
  if ($group->value === $selectedKeyword) {
    buildList($group);
  }
}

function buildList($group)
{
  foreach ($group->data as $listItem) {
    echo "<li><p>" . $listItem->month . "</p></li>";
    echo "<li><p>" . $listItem->popularity . "</p></li>";
  }
}


function getSource($dataCollection, $key)
{
  foreach ($dataCollection as $entry) {
    if ($entry->source === $key) {
      return $entry;
    }
  } 
}

Upvotes: 1

Related Questions