Little issue, how to correct check JSON, recieved with GET by codeception.
Here it come..
{
"brands":[
{
"letter":"b",
"list":[
{
"text_ident":"brand1",
"title":"brand1",
"shortDescription":"brand1brand1"
},
{
"text_ident":"brand2",
"title":"brand2",
"shortDescription":"brand2brand2"
},
{
"text_ident":"brand3",
"title":"brand3",
"shortDescription":"brand3brand3"
}
]
},
{
"letter":"v",
"list":[
{
"text_ident":"vrand3",
"title":"vrand3",
"shortDescription":"vrand3vrand3"
}
]
}
]
}
And here is the BrandsMenuCept.php test
I start it with...
$fix = new app\tests\api\v1\fixtures\BrandsFixture();
$fix->load();
$I = new ApiTester($scenario);
$I->wantTo('test GET v1/brands/menu');
$I->sendGet('http://example.com/v1/brands/menu');
$I->seeResponseCodeIs('200');
$I->seeResponseIsJson();
$I->seeResponseJsonMatchesJsonPath('$.brands');
...
And what i should write after, how to check multiple arrays?
You can do this way:
First json_decode the response with true parameter like this
$responsearr=json_decode($json, true);
Then you can check the count of the array like this:
if(count($responsearr)>0){
//logic follows here...
}else{
//invalid json message comes here
}
Related
I couldn't find an answer, so I decided to ask.
I get this response from an API:
[
{
"seasonNumber":1,
"numWins":1,
"numHighBracket":2,
"numLowBracket":2,
"seasonXp":111,
"seasonLevel":5,
"bookXp":0,
"bookLevel":1,
"purchasedVIP":false
},
{
"seasonNumber":2,
"numWins":1,
"numHighBracket":21,
"numLowBracket":31,
"seasonXp":1651,
"seasonLevel":25,
"bookXp":9,
"bookLevel":11,
"purchasedVIP":false
},
{
"seasonNumber":3,
"numWins":9,
"numHighBracket":57,
"numLowBracket":127,
"seasonXp":4659,
"seasonLevel":68,
"bookXp":0,
"bookLevel":100,
"purchasedVIP":true
},
{
"seasonNumber":4,
"numWins":8,
"numHighBracket":19,
"numLowBracket":36,
"seasonXp":274,
"seasonLevel":33,
"bookXp":7,
"bookLevel":35,
"purchasedVIP":true
}
]
I am trying to change the json data to this:
{
"seasons":
[
{
"season":1,
"battle_pass":false
},
{
"season":2,
"battle_pass":false
},
{
"season":3,
"battle_pass":true
},
{
"season":4,
"battle_pass":true
}
]
}
In my current code I am using regex like this:
preg_match_all("/(?:\{\"seasonNumber\"\:(\w)|purchasedVIP\"\:(\w+))/", $response, $seasons);
echo '{"seasons":'.json_encode($seasons, JSON_FORCE_OBJECT, JSON_PRETTY_PRINT).'}';
It's basically putting everything in a separate array but that's not what I want.
Decode the json, restructure the data, re-encode.
Code: (Demo)
// your $json =
foreach (json_decode($json) as $set) {
$array[] = ["season" => $set->seasonNumber, "battle_pass" => $set->purchasedVIP];
}
echo json_encode(["seasons" => $array]);
Output:
{"seasons":[{"season":1,"battle_pass":false},{"season":2,"battle_pass":false},{"season":3,"battle_pass":true},{"season":4,"battle_pass":true}]}
p.s. if you want to force objects and pretty print, separate those flags with a pipe (|). https://3v4l.org/qsPb0
Here is my JSON File that contains my items. I would like to search for the item name and return the id.
CODE:
$jsonitem = file_get_contents("data.json");
$objitems = json_decode($jsonitem);
$findById = function($id) use ($objname) {
foreach (json_decode($objname) as $friend) {
if ($friend->id === $id) return $friend->name;
}
return;
};
echo $findById('6') ?: 'No record found.';
JSON FILE:
[
{
"id":1,
"name":"Candy Wrapper",
"value":500,
},
{
"id":2,
"name":"Torch",
"value":2000,
}
]
Your logic is correct, but you have a couple of errors in your code:
You are referencing $objname, which is not set
You are decoding the data twice
As #Mikey pointed out, your JSON is invalid because of trailing commas on the "values" lines.
Try:
$findById = function($id) use ($objitems) {
foreach ($objitems as $friend) {
if ($friend->id == $id) return $friend->name;
}
return false;
};
for($i=0;$i<count($storetag);$i++){
$user=mysqli_query($con,"select user_id,profile_image_url from Wheel_User where user_id='$storetag[$i]'");
if(mysqli_num_rows($user)==0){
//For failure status if session id is wrong.
//http_response_code(404);
echo json_encode(array("status"=>"404","error"=>"Sorry, post id does not exists.".die()));
}
else{
$json_responce1=array();
while ($row = $user->fetch_array()){
$row_array['user_id'][$i]=explode(',',$row['user_id']);
$row_array['profile_image_url'[$i]=$row['profile_image_url'];
}
}
}
array_push($json_responce1,$row_array);
echo str_replace('\/','/', json_encode(array($json_responce1)));
It returns the following JSON
{
user_id: [3]
"1234",
"31332",
"12412"
profile_image_url: [3]
"localhost/1234.com",
"localhost/2345.com",
"localhost/3456.com"
}
but i want the json format like this
"user_id":[
{
"id":"1234",
"url":"localhost/1234.com"
},
{
"id":"1234",
"url":"localhost/1234.com"
},
{
"id":"1234",
"url":"localhost/1234.com"
}
]
You want to organise your array slightly different.
Try this
$row_array['user_id'][$i]['id']=explode(',',$row['user_id']);
$row_array['user_id'][$i]['url']=$row['profile_image_url'];
Everything should be within user_id and then by putting the $i before $id and $url, you will be grouping them as required.
I have this problem where an API responds to me with DEPARTURESEGMENT sometimes containing only one object, and sometimes containing an array of objects. Depending on which case it is, I seem to need different logics in my foreach-loop.
Response A:
{
"getdeparturesresult":{
"departuresegment":[{
"departure":{
"location":{
"#id":"7461018",
"#x":"12.523958",
"#y":"57.938402",
"name":"Noltorps centrum"
},
"datetime":"2014-12-04 23:05"
},
"direction":"Alingsås station",
"segmentid":{
"mot":{
"#displaytype":"B",
"#type":"BLT",
"#text":"Buss"
},
"carrier":{
"name":"Västtrafik",
"url":"http://www.vasttrafik.se/",
"id":"279",
"number":"1"
}
}
},
{
"departure":{
"location":{
"#id":"7461018",
"#x":"12.523958",
"#y":"57.938402",
"name":"Noltorps centrum"
},
"datetime":"2014-12-04 23:05"
},
"direction":"Alingsås station",
"segmentid":{
"mot":{
"#displaytype":"B",
"#type":"BLT",
"#text":"Buss"
},
"carrier":{
"name":"Västtrafik",
"url":"http://www.vasttrafik.se/",
"id":"279",
"number":"1"
}
}
}
]
}
}
Works with this loop:
foreach ($apiData->getdeparturesresult->departuresegment as $m) {
While this response B:
{
"getdeparturesresult":{
"departuresegment":{
"departure":{
"location":{
"#id":"7461018",
"#x":"12.523958",
"#y":"57.938402",
"name":"Noltorps centrum"
},
"datetime":"2014-12-04 23:05"
},
"direction":"Alingsås station",
"segmentid":{
"mot":{
"#displaytype":"B",
"#type":"BLT",
"#text":"Buss"
},
"carrier":{
"name":"Västtrafik",
"url":"http://www.vasttrafik.se/",
"id":"279",
"number":"1"
}
}
}
}
}
needs a loop like this (otherwise it throws an error):
foreach ($apiData->getdeparturesresult as $m) {
Is there a way to write the loop failsafe for whether DEPARTURESEGMENT is an array of objects or just one object (the brackets [] is the only difference to the structure of the json right?) or do I have to somehow test and see first whether DEPARTURESEGMENT is an array or not, and dispatch to two different loops depending on the outcome?
You have a few methods that can help you:
is_array
is_object
instanceof // if you receive specific object
gettype
json_decode second parameter, which if is set to true, tries to decode the json as an array
In you situation, you would probably be fine by doing the following:
if (is_object($entry)) {
handleObject($entry);
} elseif (is_array($entry) && count($entry)) {
foreach ($entry as $e) {
handleObject($e);
}
}
I have this little useful function in my standard repertoire:
function iter($x) {
if(is_array($x))
return $x;
if(is_object($x)) {
if($x instanceof \Iterator)
return $x;
if(method_exists($x, 'getIterator'))
return $x->getIterator();
return get_object_vars($x);
}
return array($x);
}
This way you can use any variable with foreach without having to check it beforehand:
foreach(iter($whatever) as $item)
...
How about checking whether it's an array or not with is_array?
I made a simple example of it's usage here - http://codepad.org/WNjbIPZF
I am writing a function which checks nested keys if it exists in JSON, but i hav stuck at place when if code is correct then it must return true or false but it is not. it returns null value
php function is
function checkNestedKeysExists($JSONRequest,$keyCheckArray){
$currentKey = current($keyCheckArray);
$JSONRequest = array_change_key_case($JSONRequest, CASE_LOWER);
if(array_key_exists($currentKey,$JSONRequest)){
if($currentKey==end($keyCheckArray)){
return true;
}
else {
array_shift($keyCheckArray);
$this->checkNestedKeysExists($JSONRequest[$currentKey],$keyCheckArray);
//echo "F";
}
}
else{
return false;
}
}
given array is
$keyCheckArray = array('data','device_info','deviceid');
and $JSONRequest is
{
"timestamp": "2014-01-01 11:11:11",
"data": {
"requestid": "bcpcvssi1",
"device_info": {
"os": "Android",
"deviceId": "123123",
"userProfile": {
"email": [
"abc#gmail.com"
],
"gender": "Male",
"age": "19",
"interest": [
"Apple",
"Banana"
]
}
}
}
}
Modify the line of your code where you make recursive call like following
return $this->checkNestedKeysExists($JSONRequest[$currentKey],$keyCheckArray);
So it will return the result of the call
pass $JSONRequest in
json_decode($JSONRequest, true);
EDIT: Sorry I got it wrong in first time.
Use array[0] instead of current() if you are shifting elements, maybe it is making a problem. And of course, do the var_dump() to check values.
$currentkey = 'data' and end($keyCheckArray) = 'deviceid'. That will never return true, hence you have no return values specified and it will return null.
two advices:
give the function with every possible way to end the function a valid return value.
create a variable for every fixed outcome like end($keyCheckArray).
If have tested your function (and edited it for testing purposes):
function checkNestedKeysExists($JSONRequest,$keyCheckArray){
$currentKey = current($keyCheckArray);
$JSONRequest = array_change_key_case($JSONRequest, CASE_LOWER);
$endValue = end($keyCheckArray);
if(array_key_exists($currentKey,$JSONRequest)){
print 'currentKey = '.$currentKey.", end = ".$endValue."<br>\n";
if($currentKey== $endValue){
return 'correct';
}else {
array_shift($keyCheckArray);
$p = checkNestedKeysExists($JSONRequest[$currentKey],$keyCheckArray);
print "p = ".$p."<br>\n";
//echo "F";
return $currentKey;
}
}
else{
return false;
}
}
The output is like this:
correct
device_info
data
I suggest you change your function into a while loop. Once you have found the requested result, return true.