Jump to content

Need guidance parsing JSON return


Go to solution Solved by .josh,

Recommended Posts

I'm having a really tough time using curl to parse the following data, which is returned as JSON via a URL. What I need to do is take the lowest 'price' found within 'sellorders' and assign it to a local variable, and then take the highest price found within 'buyorders' and assign that to a second local variable. Any help here is greatly appreciated.

{"success":1,"return":{"test":{"marketid":"32","label":"test\/TEST1","primaryname":"TestItem","primarycode":"ABC","secondaryname":
"Tester","secondarycode":"TES","sellorders":[{"price":"0.00002894","quantity":"13.31323200","total":"0.00038528"},{"price":"0.00002895","quantity":"92.80350000","total":"0.00268666"},{"price":"0.00002897","quantity":"392.60350000","total":"0.01137372"},{"price":"0.00002900","quantity":"392.50350000","total":"0.01138260"},{"price":"0.00002902","quantity":"785.40700000","total":"0.02279251"},],"buyorders":[{"price":"0.00002734","quantity":"93.16130210","total":"0.00254703"},{"price":"0.00002733","quantity":"2.00000000","total":"0.00005466"},{"price":"0.00002731","quantity":"2.31057540","total":"0.00006310"},{"price":"0.00002599","quantity":"3.73174150","total":"0.00009699"}]}}}

Link to comment
https://forums.phpfreaks.com/topic/286046-need-guidance-parsing-json-return/
Share on other sites

Your first problem is that this is an invalid JSON string so php (or js) won't parse it. There's a trailing comma in your array list (highlighted red). Until you fix that (make sure the JSON string you receive is valid), you aren't going to have much luck moving forward.

 

{"success":1,"return":{"test":{"marketid":"32","label":"test\/TEST1","primaryname":"TestItem","primarycode":"ABC","secondaryname":

"Tester","secondarycode":"TES","sellorders":[{"price":"0.00002894","quantity":"13.31323200","total":"0.00038528"},{"price":"0.00002895","quantity":"92.80350000","total":"0.00268666"},{"price":"0.00002897","quantity":"392.60350000","total":"0.01137372"},{"price":"0.00002900","quantity":"392.50350000","total":"0.01138260"},{"price":"0.00002902","quantity":"785.40700000","total":"0.02279251"},],"buyorders":[{"price":"0.00002734","quantity":"93.16130210","total":"0.00254703"},{"price":"0.00002733","quantity":"2.00000000","total":"0.00005466"},{"price":"0.00002731","quantity":"2.31057540","total":"0.00006310"},{"price":"0.00002599","quantity":"3.73174150","total":"0.00009699"}]}}}

As far as getting the data.. I fixed the json formatting issue in the example; you need to do that in your own code to make it work. This code sorts the sellorders array by price, lowest to highest, and then the buyorders array by price, highest to lowest. Then it's just a matter of assigning the first price in each array.

 

$data='{"success":1,"return":{"test":{"marketid":"32","label":"test\/TEST1","primaryname":"TestItem","primarycode":"ABC","secondaryname":"Tester","secondarycode":"TES","sellorders":[{"price":"0.00002894","quantity":"13.31323200","total":"0.00038528"},{"price":"0.00002895","quantity":"92.80350000","total":"0.00268666"},{"price":"0.00002897","quantity":"392.60350000","total":"0.01137372"},{"price":"0.00002900","quantity":"392.50350000","total":"0.01138260"},{"price":"0.00002902","quantity":"785.40700000","total":"0.02279251"}],"buyorders":[{"price":"0.00002734","quantity":"93.16130210","total":"0.00254703"},{"price":"0.00002733","quantity":"2.00000000","total":"0.00005466"},{"price":"0.00002731","quantity":"2.31057540","total":"0.00006310"},{"price":"0.00002599","quantity":"3.73174150","total":"0.00009699"}]}}}';
$data=json_decode(trim($data),true);

usort(
  $data['return']['test']['sellorders'],
  function($a,$b) {
    if ($a == $b) return 0;
    return ($a['price'] < $b['price']) ? -1 : 1;
  }
);

usort(
  $data['return']['test']['buyorders'],
  function($a,$b) {
    if ($a == $b) return 0;
    return ($a['price'] < $b['price']) ? 1 : -1;
  }
);

$lowest_sellorder = $data['return']['test']['sellorders'][0]['price'];
$highest_buyorder = $data['return']['test']['buyorders'][0]['price'];
['test'] is part of your JSON structure.. I used exactly what you posted, except for fixing the comma. 

 

 

Understood, but the issue here is that using 'test' could be a problem, as that attribute will change from time to time.  The names 'return', 'sellorders', and 'buyorders' on the other hand, will always remain the same - so they can be utilized to sort and parse.  

 

'test' can't be hardcoded, so I was trying to figure out the exact need for it in the structure of your code... and if there is a way around utilizing it.

Perhaps I am mistaken, but I'm getting the impression you thought you mentioned this already. If you will refer to your original post, that requirement/limitation was never mentioned. Regardless, the point I'm making here is that I can only go off the info/code you show. On that note..

 

Is there only ever going to be one element in that 2nd level, or can that 2nd level have more than one element? If there can be more than one element in that 2nd level, will the one you need to pull data from always be in a certain position (i.e. the first one in the list)? Or, you said the element name can change.. will it only be a certain feasibly finite set of values?

 

Basically, making that 2nd level reference dynamic can be really easy or it can be basically impossible, or somewhere in between. It depends on what the expected JSON structure/format is. You need some sort of way to uniquely target it.

Perhaps I am mistaken, but I'm getting the impression you thought you mentioned this already. If you will refer to your original post, that requirement/limitation was never mentioned. Regardless, the point I'm making here is that I can only go off the info/code you show. On that note..

 

Is there only ever going to be one element in that 2nd level, or can that 2nd level have more than one element? If there can be more than one element in that 2nd level, will the one you need to pull data from always be in a certain position (i.e. the first one in the list)? Or, you said the element name can change.. will it only be a certain feasibly finite set of values?

 

Basically, making that 2nd level reference dynamic can be really easy or it can be basically impossible, or somewhere in between. It depends on what the expected JSON structure/format is. You need some sort of way to uniquely target it. 

 

 

 

Very sorry about that.  You're correct.  I thought I had included that piece of information in my original post.  Below is the JSON response once again, this time with the dynamic element names (those that can change) highlighted in red.  It can be assumed that those names not highlighted in red will always remain as is.

 

{"success":1,"return":{"test":{"marketid":"32","label":"test\/TEST1","primaryname":"TestItem","primarycode":"ABC","secondaryname":

"Tester","secondarycode":"TES","sellorders":[{"price":"0.00002894","quantity":"13.31323200","total":"0.00038528"},{"price":"0.00002895","quantity":"92.80350000","total":"0.00268666"},{"price":"0.00002897","quantity":"392.60350000","total":"0.01137372"},{"price":"0.00002900","quantity":"392.50350000","total":"0.01138260"},{"price":"0.00002902","quantity":"785.40700000","total":"0.02279251"}],"buyorders":[{"price":"0.00002734","quantity":"93.16130210","total":"0.00254703"},{"price":"0.00002733","quantity":"2.00000000","total":"0.00005466"},{"price":"0.00002731","quantity":"2.31057540","total":"0.00006310"},{"price":"0.00002599","quantity":"3.73174150","total":"0.00009699"}]}}}





			
				


	Edited  by nydeveloper
	
	

			
		
  • Solution

Okay, so if that's the only stuff that will change in the JSON string you are receiving, you can do this:

 

$data='{"success":1,"return":{"test":{"marketid":"32","label":"test\/TEST1","primaryname":"TestItem","primarycode":"ABC","secondaryname":"Tester","secondarycode":"TES","sellorders":[{"price":"0.00002894","quantity":"13.31323200","total":"0.00038528"},{"price":"0.00002895","quantity":"92.80350000","total":"0.00268666"},{"price":"0.00002897","quantity":"392.60350000","total":"0.01137372"},{"price":"0.00002900","quantity":"392.50350000","total":"0.01138260"},{"price":"0.00002902","quantity":"785.40700000","total":"0.02279251"}],"buyorders":[{"price":"0.00002734","quantity":"93.16130210","total":"0.00254703"},{"price":"0.00002733","quantity":"2.00000000","total":"0.00005466"},{"price":"0.00002731","quantity":"2.31057540","total":"0.00006310"},{"price":"0.00002599","quantity":"3.73174150","total":"0.00009699"}]}}}';
$data=json_decode(trim($data),true);

$key2 = key($data['return']);
usort(
  $data['return'][$key2]['sellorders'],
  function($a,$b) {
    if ($a == $b) return 0;
    return ($a['price'] < $b['price']) ? -1 : 1;
  }
);

usort(
  $data['return'][$key2]['buyorders'],
  function($a,$b) {
    if ($a == $b) return 0;
    return ($a['price'] < $b['price']) ? 1 : -1;
  }
);

$lowest_sellorder = $data['return'][$key2]['sellorders'][0]['price'];
$highest_buyorder = $data['return'][$key2]['buyorders'][0]['price'];

hmm... see that suggests you are using an older version of php that doesn't support anonymous functions.. but it worked for you before, with the hardcoded 'test' element, right? So changing it to $key2 should have worked.. Are you testing this in a different environment?

yeah.. anonymous functions are 5.3+

 

If you can't upgrade right now, do it like this instead:

 

$data='{"success":1,"return":{"test":{"marketid":"32","label":"test\/TEST1","primaryname":"TestItem","primarycode":"ABC","secondaryname":"Tester","secondarycode":"TES","sellorders":[{"price":"0.00002894","quantity":"13.31323200","total":"0.00038528"},{"price":"0.00002895","quantity":"92.80350000","total":"0.00268666"},{"price":"0.00002897","quantity":"392.60350000","total":"0.01137372"},{"price":"0.00002900","quantity":"392.50350000","total":"0.01138260"},{"price":"0.00002902","quantity":"785.40700000","total":"0.02279251"}],"buyorders":[{"price":"0.00002734","quantity":"93.16130210","total":"0.00254703"},{"price":"0.00002733","quantity":"2.00000000","total":"0.00005466"},{"price":"0.00002731","quantity":"2.31057540","total":"0.00006310"},{"price":"0.00002599","quantity":"3.73174150","total":"0.00009699"}]}}}';
$data=json_decode(trim($data),true);

$key2 = key($data['return']);

function sell_sort($a,$b) {
  if ($a == $b) return 0;
  return ($a['price'] < $b['price']) ? -1 : 1;
}
usort(
  $data['return'][$key2]['sellorders'],
  'sell_sort'
);

function buy_sort($a,$b) {
  if ($a == $b) return 0;
  return ($a['price'] < $b['price']) ? 1 : -1;
}
usort(
  $data['return'][$key2]['buyorders'],
  'buy_sort'
);

$lowest_sellorder = $data['return'][$key2]['sellorders'][0]['price'];
$highest_buyorder = $data['return'][$key2]['buyorders'][0]['price'];

I was able to upgrade my PHP version, and the code worked perfectly!  Thanks so much!

 

The next step now is to pull that JSON response from a URL as opposed to having it hardcoded.  This is my approach, and it works just fine, but I'm wondering if this is the most efficient method.  What are your thoughts on this?

 

$ch = curl_init(); 


// set url 

 curl_setopt($ch, CURLOPT_URL, "<URL GOES HERE>"); 



 //return the transfer as a string 
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 


 // $output contains the output string 
 $data = curl_exec($ch); 


  // close curl resource to free up system resources 
  curl_close($ch);


$data=json_decode(trim($data),true);

well, you could probably just use file_get_contents as-is, but using cURL may be a better future-proof approach. If the server you are making the request to decides to change things up by putting up a login barrier or check if request is made from a browser, etc.. you will more easily get around that using cURL than file_get_contents.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.