Recursive JSON transformation - php

Suppose I have a JSON string:
$json = '{"lemon":"test",
"orange":["toto", "tata", "tete"],
"zob":[{"id":"0"}, {"id":"1"}]}';
I'd like to cycle through that encoded object to modify every string in it, so I have a recursive function:
function doObject($__obj){
$__obj = cycleObject($__obj);
return $__obj;
}
function cycleObject($__obj){
$type = gettype($__obj);
foreach($__obj as $var => &$val){
switch(gettype($val)){
case 'object':
cycleObject($val);
break;
case 'array':
cycleObject($val);
break;
case 'string':
if($type == 'object'){
$__obj->$var = $val.'-ok';
}else{
if($type == 'array'){
$__obj[$var] = $val.'-ok';
}
}
break;
}
}
return $__obj;
}
And I call the function:
$obj = doObject(json_decode($json));
var_dump($obj);
Which gives :
object(stdClass)#1 (3) {
["lemon"]=> string(7) "test-ok"
["orange"]=> array(3) {
[0]=> string(4) "toto"
[1]=> string(4) "tata"
[2]=> string(4) "tete" }
["zob"]=> array(2) {
[0]=> object(stdClass)#2 (1) {
["id"]=> string(4) "0-ok" }
[1]=> object(stdClass)#3 (1) {
["id"]=> string(4) "1-ok" }
}
}
Now my problem is, for some reason, I am unable to modify directly inside an array composed by string, or should I say, the modified string inside an array (and not inside an object inside an array) because the array loses its reference. How do I fix that so in orange I instead obtain:
[0]=> string(7) "toto-ok"
[1]=> string(7) "tata-ok"
[2]=> string(7) "tete-ok"

Your array of strings isn't being scrutinized correctly by your function. Basically, in each array you need a second check to see if you are dealing with another array/object or a string, otherwise regular arrays of strings are being bypassed....oddly enough. The following should work for you:
$json = '{"lemon":"test",
"orange":["toto", "tata", "tete"],
"zob":[{"id":"0"}, {"id":"1"}]}';
function doObject($__obj){
$__obj = cycleObject($__obj);
return $__obj;
}
function cycleObject($__obj){
foreach($__obj as $key => &$val){
if(is_object($val)) {
cycleObject($val);
}
if(is_array($val)) {
foreach($val as &$v) {
if(is_object($v) || is_array($v)) {
cycleObject($v);
} else {
$v .= '-ok';
}
}
}
if(is_string($val)) {
$val .= '-ok';
}
}
return $__obj;
}
$obj = doObject(json_decode($json));
var_dump($obj);
This produced the results you were looking for in my local environment.
object(stdClass)#1 (3) {
["lemon"]=>
string(7) "test-ok"
["orange"]=>
array(3) {
[0]=>
string(7) "toto-ok"
[1]=>
string(7) "tata-ok"
[2]=>
string(7) "tete-ok"
}
["zob"]=>
array(2) {
[0]=>
object(stdClass)#2 (1) {
["id"]=>
string(4) "0-ok"
}
[1]=>
object(stdClass)#3 (1) {
["id"]=>
string(4) "1-ok"
}
}
}

Related

Optimizing PHP code with two foreach loops

I have an array that consists of the keys:
$countries = ['EU', 'UK', 'Asia'];
Another array that consists of further elements based on those keys:
$countries_array=['UK'=>['London', 'Birmingham', 'Manchester'], 'EU'=> ['Germany','Netherlands'] , 'Asia'=> ['Pakistan','Bangladesh','China']];
$mid_countries[];
I want to pass through all the elements, check if they are empty or not and then further create another array. I have written a code and it works fine. But it has foreach loops. Is there any way that I could optimize this code?
foreach ($countries as $each_country) {
if (!empty($countries_array["$each_country"][0])) {
foreach ($countries_array["$each_country"] as $value) {
$mid_countries[] = array("wildcard" => array("$each_country" => $value. "*"));
}
}
}
Expected result:
array(8) {
[0]=> array(1) { ["wildcard"]=> array(1) { ["EU"]=> string(8) "Germany*" } } [1]=> array(1) { ["wildcard"]=> array(1) { ["EU"]=> string(12) "Netherlands*"}}
[2]=> array(1) { ["wildcard"]=> array(1) { ["UK"]=> string(7) "London*" } } [3]=> array(1) { ["wildcard"]=> array(1) { ["UK"]=> string(11) "Birmingham*" } } [4]=> array(1) { ["wildcard"]=> array(1) { ["UK"]=> string(11) "Manchester*" } } [5]=> array(1) { ["wildcard"]=> array(1) { ["Asia"]=> string(9) "Pakistan*" } } [6]=> array(1) { ["wildcard"]=> array(1) { ["Asia"]=> string(11) "Bangladesh*"}}
[7]=> array(1) { ["wildcard"]=> array(1) { ["Asia"]=> string(6) "China*" } } }
I think you expected this (Code updated use its working in single loop)
foreach ($countries_array as $key=>$value) {
$tmp=implode('*#'.$key.'#',$value);
$tmp='#'.$key.'#'.$tmp."*";
$tmp=str_replace('#'.$key.'#',"\"}},{\"wildcard\":{\"".$key."\":\"",$tmp);
$result=$result.substr($tmp,3)."\"}}";
}
$result="[".ltrim($result,"\"}},")."]";
$result=json_decode($result,true);
print_r($result);

Assigning specific element of multidimensional array in url in php

My goal is to get specific element/value from a multidimensional array and assign them in a URL in loop. I have already tried and was able to get elements in the array but this displays all elements. I only want to get specific, like nid and field_x values.
This is my link structure: http://localhost:8080/$nid/$field_x
Expected result:
http://localhost:8080/123/one
http://localhost:8080/789/three
This is my sample var_dump result
array(1) {
[0]=>
array(38) {
["nid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(123)
}
}
["vid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(456)
}
}
["field_x"]=>
array(1) {
[0]=>
array(4) {
["target_id"]=>
string(6) "One"
}
}
["field_y"]=>
array(1) {
[0]=>
array(4) {
["target_id"]=>
string(2) "Two"
}
}
}
[1]=>
array(38) {
["nid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(789)
}
}
["vid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(321)
}
}
["field_x"]=>
array(1) {
[0]=>
array(4) {
["target_id"]=>
string(6) "Three"
}
}
["field_y"]=>
array(1) {
[0]=>
array(4) {
["target_id"]=>
string(2) "Four"
}
}
}
}
You can use a foreach() and get the data using $values['nid'][0]['value'] or $values['field_x'][0]['target_id']:
foreach ($result as $values) {
$nid = $values['nid'][0]['value'];
$field_x = $values['field_x'][0]['target_id'];
echo "http://localhost:8080/$nid/$field_x" ;
}
Will outputs:
http://localhost:8080/123/One
http://localhost:8080/789/Three
You probably want to do something else than an echo, so you can create a new array:
$urls = [];
foreach ($result as $values) {
$nid = $values['nid'][0]['value'];
$field_x = $values['field_x'][0]['target_id'];
$urls[] = "http://localhost:8080/$nid/$field_x" ;
}
print_r($urls);

Output and use array elements from a REST Api call in php

I am calling a REST Api to get data using curl in php. It gives me the list of data/contents in the api in Array php format.
I was able to get single element value using $resultArray[0]['nid'][0]['value'];. But my goal is to get elements in all contents in the api.
Say I want to get the following elements in the nested arrays.
$resultArray[0]['nid'][0]['value'];
$resultArray[0]['vid'][0]['value'];
$resultArray[0]['cid'][0]['value'];
And use these values in a loop too.
I am trying to search how I can do it loop, and if anyone can provide sample code, that would be appreciated.
Update:
This is the sample result of var_dump:
array(1) {
[0]=>
array(38) {
["nid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(1)
}
}
["vid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(2)
}
}
["cid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(3)
}
}
["field"]=>
array(1) {
[0]=>
array(4) {
["target_id"]=>
int(4)
}
}
}
[1]=>
array(38) {
["nid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(11)
}
}
["vid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(22)
}
}
["cid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(33)
}
}
["field"]=>
array(1) {
[0]=>
array(4) {
["target_id"]=>
int(44)
}
}
}
[2]=>
array(38) {
["nid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(111)
}
}
["vid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(222)
}
}
["cid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(333)
}
}
["field"]=>
array(1) {
[0]=>
array(4) {
["target_id"]=>
int(444)
}
}
}
}
And I want to use these elements values in a loop.
Say my expected result is.
Test1 = "1", "2", "3"
Test2 = "11", "22", "33"
Test3 = "111", "222", "333"
These equivalent numbers should be comming from the element nid, vid, cid.
I dont just want to assign/echo these values in the result as I have array[100s] in one api call.
Since your array is a multidimensional array, you need to have nested foreach loops:
$test = 1;
foreach ($resultArray as $items) {
// Echo the current test number
echo "Test{$test} = ";
$values = [];
foreach ($items as $item) {
// Get the correct value.
if (array_key_exists('value', $item[0])) {
$values[] = $item[0]['value'];
continue;
}
if (array_key_exists('target_id', $item[0])) {
$values[] = $item[0]['target_id'];
continue;
}
}
echo '"' . implode('", "', $values) . '"' . "\n";
$test++;
}
Demo: https://3v4l.org/fnHlV

How to make the number from an array/ json_string negative

So I have an array stored in a variable called $data that looks like this:
["data"]=>
["rows"]=>
array(30) {
[0]=>
array(3) {
[0]=>
string(10) "2016-08-15"
[1]=>
int(0)
[2]=>
int(0)
}
[1]=>
array(3) {
[0]=>
string(10) "2016-08-16"
[1]=>
int(0)
[2]=>
int(0)
}
[2]=>
array(3) {
[0]=>
string(10) "2016-08-17"
[1]=>
int(0)
[2]=>
int(0)
}
[3]=>
array(3) {
[0]=>
string(10) "2016-08-18"
[1]=>
int(0)
[2]=>
int(0)
}
By using the following function I take the values from the array:
$subscribersGained = [];
foreach ($data->data->rows as $obj) {
if (isset($obj[1])) {
// add the element to the beginning of the array
array_unshift($subscribersGained, $obj[1]);
}
if(count($subscribersGained) >= 30) {
break;
}
}
$gained = array_map( create_function('$value', 'return (int)$value;'),
$subscribersGained);
echo json_encode($gained);
And store them into a json_string that looks like this:
[0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
What I need to do is that I have to make the non 0 number be negative. So in this case I want to have -1 not 1. Any ideas how to make that happen? Thank you for your time!
Well, the most primitive way to do it that I figure out it is:
foreach($array as $key => $number) {
$array[$key] = 0 - $number;
}
$gained = array(0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
$gained = array_map(function($el) { return 0-$el; }, $gained);
print_r($gained);
//from #Dmytrechko`s code

Get value in PHP from JSON

I need to get the objects information for "label", "name" where value=true in a PHP variable and not were value=false.
How is this done with this JSON array?
If I make a var_dump of the JSON I get this:
array(8) {
[0]=>
object(stdClass)#8 (3) {
["label"]=>
string(4) "Name"
["name"]=>
string(7) "txtName"
["value"]=>
bool(true)
}
[1]=>
object(stdClass)#9 (3) {
["label"]=>
string(6) "E-mail"
["name"]=>
string(8) "txtEmail"
["value"]=>
bool(true)
}
[2]=>
object(stdClass)#10 (3) {
["label"]=>
string(12) "Phone Number"
["name"]=>
string(8) "txtPhone"
["value"]=>
bool(false)
}
[3]=>
object(stdClass)#11 (3) {
["label"]=>
string(19) "Mobile Phone Number"
["name"]=>
string(14) "txtMobilePhone"
["value"]=>
bool(false)
}
}
$arr = array();
$i = 0;
foreach($json as $key => $items) {
if($items->value == true) {
$arr[$i]['label'] = $items->label;
$arr[$i]['name'] = $items->name;
$i++;
}
}
You can decode it as an object or an array, in this example I use an array.
First you want to take the JSON encoded information and decode it into a PHP array, you can use json_decode() for this:
$data = json_decode($thejson,true);
//the Boolean argument is to have the function return an array rather than an object
Then you can loop through it as you would a normal array, and build a new array containing only elements where 'value' matches your needs:
foreach($data as $item) {
if($item['value'] == true) {
$result[] = $item;
}
}
You then have the array
$result
at your disposal.
Simplification of the suggestions proposed by users JohnnyFaldo and som:
$data = json_decode($thejson, true);
$result = array_filter($data, function($row) {
return $row['value'] == true;
});

Categories