1

EDIT#4: json_decode is failing and returning null on a seemingly valid json string. See below for more info

I am new to JSON/JSONP and I'm running into constant trouble accessing the values in the returned JSON with PHP. I have stripped the JSONP callback without issue using code I found on this board. I am getting a JSONP result from http://www.google.com/dictionary/json?callback=a&sl=en&tl=en&q=love and struggling to access the first result for the meaning. It's a quite complex result, and I need to access the first meaning (in the node "text") from the below JSON result.

http://pastebin.com/hBTeBTUL

My best attempt was:

  if (isset($json->primaries[1]->entries[1]->terms[1]->text))

The above was the best I could do, I just keep getting errors trying to return that text node saying it is undefined. I'd prefer to work with objects rather than associative arrays too, if possible, so please avoid telling me to set it to return assoc array.

Any help would be greatly appreciated. I'm really stuck :P

EDIT:

$json->primaries[1]->entries[1]->terms[0]->text didn't seem to work either. Here is the complete script. Ignore the $params array as it is not used, was going to use it to generate the query.

The script has been edited since when I first posted, I had an invalid JSON object, but the error seems to be fixed as it will now parse through JSON formatters.

The error i'm getting trying to print the value out is

PHP Notice: Trying to get property of non-object in /home/outil2/Plugins/GDefine.php on line 23

EDIT#2: added json_decode which was in my original solution, but got lost in the second version

<?php
class GDefine extends Plugin {

    public static $enabled = TRUE;

    public function onReceivedData($data) {
            if ($data["message"][0] == ".def") {
                    $params = array (
                            "callback" => "a",
                            "sl" => "en",
                            "tl" => "en",
                            "q" => $data["message"][1]
                    );

                    $jsonp = file_get_contents(
                            "http://www.google.com/dictionary/json?callback=a&sl=en&tl=en&q=" . $data["message"][1]);


                    $json = json_decode(substr($jsonp, 2, strlen($jsonp)-12));

                    var_dump($json);

                    print_r($json->primaries[1]->entries[1]->terms[0]->text);

                    if (isset($json->primaries[1]->entries[1]->terms[0]->text)) {

                            $text = $this->bold("Google Definition: ");
                            $text .= $this->teal($json->primaries[1]->entries[1]->terms[0]->text);
                            $this->privmsg($data["target"], $text);
                    } else {

                    $this->privmsg($data["target"], "error error error");

                    }
            }
    }
}

EDIT #3: this is the string I'm trying to json_decode, after using substr to remove the callback function, but am getting a NULL value returned on var_dump($json)

{"query":"love","sourceLanguage":"en","targetLanguage":"en","primaries":[{"type":"headword","terms":[{"type":"text","text":"love","language":"en","labels":[{"text":"Noun","title":"Part-of-speech"}]},{"type":"phonetic","text":"/lÉv/","language":"und"},{"type":"sound","text":"http://www.gstatic.com/dictionary/static/sounds/de/0/love.mp3","language":"und"}],"entries":[{"type":"related","terms":[{"type":"text","text":"loves","language":"und","labels":[{"text":"plural"}]}]},{"type":"meaning","terms":[{"type":"text","text":"An intense feeling of deep affection","language":"en"}],"entries":[{"type":"example","terms":[{"type":"text","text":"babies fill parents with intense feelings of \x3cem\x3elove\x3c/em\x3e","language":"en"}]},{"type":"example","terms":[{"type":"text","text":"their \x3cb\x3e\x3cem\x3elove\x3c/em\x3e for\x3c/b\x3e their country","language":"en"}]}]},{"type":"meaning","terms":[{"type":"text","text":"A deep romantic or sexual attachment to someone","language":"en"}],"entries":[{"type":"example","terms":[{"type":"text","text":"it was \x3cem\x3elove\x3c/em\x3e at first sight","language":"en"}]},{"type":"example","terms":[{"type":"text","text":"they were both \x3cb\x3ein \x3cem\x3elove\x3c/em\x3e with\x3c/b\x3e her","language":"en"}]},{"type":"example","terms":[{"type":"text","text":"we were slowly \x3cb\x3efalling in \x3cem\x3elove\x3c/em\x3e\x3c/b\x3e","language":"en"}]}]},{"type":"meaning","terms":[{"type":"text","text":"A personified figure of \x3cem\x3elove\x3c/em\x3e, often represented as Cupid","language":"en"}]},{"type":"meaning","terms":[{"type":"text","text":"A great interest and pleasure in something","language":"en"}],"entries":[{"type":"example","terms":[{"type":"text","text":"his \x3cb\x3e\x3cem\x3elove\x3c/em\x3e for\x3c/b\x3e football","language":"en"}]},{"type":"example","terms":[{"type":"text","text":"we share a \x3cb\x3e\x3cem\x3elove\x3c/em\x3e of\x3c/b\x3e music","language":"en"}]}]},{"type":"meaning","terms":[{"type":"text","text":"Affectionate greetings conveyed to someone on one\x27s behalf","language":"en"}]},{"type":"meaning","terms":[{"type":"text","text":"A formula for ending an affectionate letter","language":"en"}],"entries":[{"type":"example","terms":[{"type":"text","text":"take care, lots of \x3cem\x3elove\x3c/em\x3e, Judy","language":"en"}]}]},{"type":"meaning","terms":[{"type":"text","text":"A person or thing that one \x3cem\x3eloves\x3c/em\x3e","language":"en"}],"entries":[{"type":"example","terms":[{"type":"text","text":"she was \x3cb\x3ethe \x3cem\x3elove\x3c/em\x3e of his life\x3c/b\x3e","language":"en"}]},{"type":"example","terms":[{"type":"text","text":"their two great \x3cem\x3eloves\x3c/em\x3e are tobacco and whiskey","language":"en"}]}]},{"type":"meaning","terms":[{"type":"text","text":"A friendly form of address","language":"en"}],"entries":[{"type":"example","terms":[{"type":"text","text":"it\x27s all right, \x3cem\x3elove\x3c/em\x3e","language":"en"}]}]},{"type":"meaning","terms":[{"type":"text","text":"Used to express affectionate approval for someone","language":"en"}],"entries":[{"type":"example","terms":[{"type":"text","text":"don\x27t fret, there\x27s a \x3cem\x3elove\x3c/em\x3e","language":"en"}]}]},{"type":"meaning","terms":[{"type":"text","text":"(in tennis, squash, and some other sports) A score of zero; nil","language":"en"}],"entries":[{"type":"example","terms":[{"type":"text","text":"\x3cem\x3elove\x3c/em\x3e fifteen","language":"en"}]},{"type":"example","terms":[{"type":"text","text":"he was down two sets to \x3cem\x3elove\x3c/em\x3e","language":"en"}]}]}]},{"type":"headword","terms":[{"type":"text","text":"love","language":"en","labels":[{"text":"Verb","title":"Part-of-speech"}]},{"type":"phonetic","text":"/lÉv/","language":"und"},{"type":"sound","text":"http://www.gstatic.com/dictionary/static/sounds/de/0/love.mp3","language":"und"}],"entries":[{"type":"related","terms":[{"type":"text","text":"loved","language":"und","labels":[{"text":"past participle"}]},{"type":"text","text":"loves","language":"und","labels":[{"text":"3rd person singular present"}]},{"type":"text","text":"loving","language":"und","labels":[{"text":"present participle"}]},{"type":"text","text":"loved","language":"und","labels":[{"text":"past tense"}]}]},{"type":"meaning","terms":[{"type":"text","text":"Feel a deep romantic or sexual attachment to (someone)","language":"en"}],"entries":[{"type":"example","terms":[{"type":"text","text":"do you \x3cem\x3elove\x3c/em\x3e me?","language":"en"}]}]},{"type":"meaning","terms":[{"type":"text","text":"Like very much; find pleasure in","language":"en"}],"entries":[{"type":"example","terms":[{"type":"text","text":"I\x27d \x3cem\x3elove\x3c/em\x3e a cup of tea, thanks","language":"en"}]},{"type":"example","terms":[{"type":"text","text":"I just \x3cem\x3elove\x3c/em\x3e dancing","language":"en"}]},{"type":"example","terms":[{"type":"text","text":"a fun-\x3cem\x3eloving\x3c/em\x3e girl","language":"en"}]}]}]}]}

I json_decode that and it returns NULL :(

Bryce
  • 46
  • 6

1 Answers1

0

You're trying to access an object that doesn't exist. Your code:

if (isset($json->primaries[1]->entries[1]->terms[1]->text)) // Doesn't exist

There's no terms[1] in entries[1] in primaries[1]. There's just 1 item; terms[0]. I think this will work for example:

if (isset($json->primaries[1]->entries[1]->terms[0]->text))

enter image description here

The first item in the array is indexed by 0 not 1, maybe that's your mistake.

Edit:

You also need to decode the JSON, change:

$json = substr($jsonp, 2, strlen($jsonp)-12);

to:

$json = json_decode(substr($jsonp, 2, strlen($jsonp)-12));

Edit:

You need to escape some unescaped characters in the JSON as well. Add this to your code:

Change:

$json = json_decode(substr($jsonp, 2, strlen($jsonp)-12));

to:

$json = substr($jsonp, 2, strlen($jsonp) - 12);
$json = str_replace("\\", "\\\\", $json);
$json = json_decode($json);
Hein Andre Grønnestad
  • 6,885
  • 2
  • 31
  • 43
  • Hi, thanks for your help, it seems to have put me towards the right path of understanding the notation, however I still get this error: PHP Notice: Trying to get property of non-object in /home/outil2/Plugins/GDefine.php on line 23 – Bryce Jul 26 '13 at 11:33
  • Ahhh, I accidentally didn't put that in on the edited code. However, I now get a NULL result printed in var_dump - does this indicate invalid json result? – Bryce Jul 26 '13 at 11:48
  • Yes, NULL is returned if decode fails. It's strange, because the JSON in your pastebin is valid according to linter. – Hein Andre Grønnestad Jul 26 '13 at 11:51
  • I think my substr statement appears to be fine, and I'm getting valid results from pasting the undecoded var_dump into a json formatter... – Bryce Jul 26 '13 at 12:00
  • Just got it to work, you have to escape some characters, I've updated the answer again. – Hein Andre Grønnestad Jul 26 '13 at 14:00
  • Seems like it only works for the query love, but I'll give you the points because you solved the question at hand. Still some work to be done getting it working for all results it seems, for example querying 'strange' or 'sex' returns errors :( – Bryce Jul 26 '13 at 14:38
  • Yes, that's because the JSON result is different for each search query. You may have to use a better method of accessing the JSON data than fixed indexes. This specific question has been answered, so it was correct to accept it. You did get a step further though! Keep working on it and post another question if you need more help. :) Good luck! – Hein Andre Grønnestad Jul 26 '13 at 15:10