I am querying a service if a person have phone number(s) (also maybe not). I have a json string (as return value) like the following:
$json = '{"data":[{"tel1":"1102"},{"tel2":"3220"}],"found":true}';
I convert this string to json_decode() function.
$jd = json_decode($json);
Then I want to get the phone numbers only into an array without keys.
if($jd->found) {
$o2a = get_object_vars($json);
}
var_dump($o2a);
When I want to see what $o2a holds with var_dump() function, I get the following:
array (size=2)
'data' =>
array (size=2)
0 =>
object(stdClass)[2]
public 'tel1' => string '1219' (length=4)
1 =>
object(stdClass)[3]
public 'tel2' => string '2710' (length=4)
'found' => boolean true
I want to get only the phone numbers into an array at the end like:
$phones = array('1219', '2710');
What makes me stop doing this is that I do not know how many phone numbers one can have. Json array could consist of more or less elements.
$possibleJson1 = '{"data":[],"found":false}'; //no phone number found
$possibleJson2 = '{"data":[{"tel1":"1102"},{"tel2":"3220"},{"tel3":"1112"},{"tel4":"3230"}],"found":true}'; //4 phone numbers found
It may vary 0-to-n, so if it was a constant number I could create that array within a loop.
Some functions without any code :)
$json = '{"data":[{"tel1":"1102"},{"tel2":"3220"}],"found":true}';
$vals = array_values(array_reduce(json_decode($json, true)['data'], 'array_merge',[]));
var_dump($vals);
Convert it into an array and then you should be able to iterate it easily
$jd = json_decode($json, true);
$phones = array();
if(isset($jd['data']) && $jd['found']) {
foreach($jd['data'] as $key => $val) $phones[] = $val;
}
Instead of handling with an object, use the second parameter of the json_decode function so it would returned an array.
Check if the data and found keys exist.
Since you don't know what are the keys names, you can use array_values
Demo
.
$jd = json_decode($json, true);
if(isset($jd['data']) && isset($jd['found'])){
$telArr = $jd['data'];
$phones = array();
foreach($telArr as $tel){
$value = array_values($tel);
$phones[] = $value[0];
}
var_dump($phones);
}
Output:
array(2) {
[0]=>
string(4) "1102"
[1]=>
string(4) "3220"
}
Well, I would try something like that:
$json = '{"data":[{"tel1":"1102"},{"tel2":"3220"}],"found":true}';
$jd = json_decode($json);
$phones = [];
if ($jd->found && count($jd->data)) {
foreach ($jd->data as $key -> $value) {
$phones[] = $value;
}
}
Try as using in_array and simple foreach loop
$json = '{"data":[{"tel1":"1102"},{"tel2":"3220"}],"found":true}';
$arr = json_decode($json, true);
$result = array();
if (in_array(true, $arr)) {
foreach ($arr['data'] as $key => $value) {
foreach($value as $k => $v)
$result[] = $v;
}
}
print_r($result);
Fiddle
Related
I have a MYSQL query that fetches an array of dictionaries or results which are returned via JSON in an api. In some cases, I would like to change the name of the dictionary keys in the results array.
For example, in the following case:
$var = '[{"player":"Tiger Woods"},{"player":"Gary Player"}]';
I would like to change it to:
$var = '[{"golfer":"Tiger Woods"},{"golfer":"Gary Player"}]'
It is not practical in this case to change the mysql query so I'd just like to replace the word "player" with the word "golfer" for the keys without disturbing the values.
In the above example, I would not want to change Gary Player's name so just using str_replace does not seem like it would work.
Is there a way to change all of the keys from "player" to "golfer" without changing any of the values?
Here is the snippet you can use
$var = '[{"player":"Tiger Woods"},{"player":"Gary Player"}]';
// json decode the json string
$temp = json_decode($var, true);
$temp = array_map(function($item){
// combining key and values
return array_combine(['golfer'], $item);
}, $temp);
print_r($temp);
// or echo json_encode($temp);
Demo.
Some argue that foreach is fastest,
foreach($temp as $k => &$v){
$v = array_combine(['golfer'], $v);
}
print_r($temp);
Demo.
Little hardcoded if more than one keys in single array,
foreach ($temp as $k => &$v){
$v['golfer'] = $v['player'];
unset($v['player']);
}
print_r($temp);
Demo.
Using recursion
function custom($arr, $newKey, $oldKey)
{
// if the value is not an array, then you have reached the deepest
// point of the branch, so return the value
if (!is_array($arr)) {
return $arr;
}
$result = []; // empty array to hold copy of subject
foreach ($arr as $key => $value) {
// replace the key with the new key only if it is the old key
$key = ($key === $oldKey) ? $newKey : $key;
// add the value with the recursive call
$result[$key] = custom($value, $newKey, $oldKey);
}
return $result;
}
$var = '[{"player":"Tiger Woods"},{"player":"Gary Player"}]';
$temp = json_decode($var, true);
$temp = replaceKey($temp, 'golfer', 'player');
print_r($temp);
Demo & source.
Using json way,
function json_change_key($arr, $oldkey, $newkey) {
$json = str_replace('"'.$oldkey.'":', '"'.$newkey.'":', json_encode($arr));
return json_decode($json, true);
}
$temp = json_change_key($temp, 'player', 'golfer');
print_r($temp);
Demo
If you want multiple key replace, here is the trick,
$var = '[{"player":"Tiger Woods", "wins":"10","losses":"3"},{"player":"Gary Player","wins":"7", "losses":6}]';
$temp = json_decode($var, true);
function recursive_change_key($arr, $set)
{
if (is_array($arr) && is_array($set)) {
$newArr = [];
foreach ($arr as $k => $v) {
$key = array_key_exists($k, $set) ? $set[$k] : $k;
$newArr[$key] = is_array($v) ? recursive_change_key($v, $set) : $v;
}
return $newArr;
}
return $arr;
}
$set = [
"player" => "golfers",
"wins" => "victories",
"losses" => "defeats"
];
$temp = recursive_change_key($temp, $set);
print_r($temp);
Demo.
$a = '[{"player":"Tiger Woods"},{"player":"Gary Player"}]';
$array = json_decode($a, true);
foreach($array as $key=>$value){
if(array_keys($value)[0] === "player"){
$array[$key] = ["golfer" => array_values($value)[0]];
};
}
echo json_encode($array);
you can write the value of the key to a new key and then delete the old.
renaming a key called "a" to "b", while keeping the value.
var json = {
"a" : "one"
}
json["b"] = json["a"];
delete json["a"];
for your example, just use this with a loop.
source: https://sciter.com/forums/topic/how-to-rename-the-key-of-json/
How can I remove string . I want to find string that've 2018 then I want to delete string until ,
{"2018-1-8":0,"2018-1-9":0,"2018-1-10":0,"2019-1-1":0,"2019-1-15":0}
How can I display like this
{"2019-1-1":0,"2019-1-15":0}
Note I want to remove "2018-1-8":0,"2018-1-9":0,"2018-1-10":0,
This string is valid JSON which you can parse using json_decode(). You can then modify the data as you want:
// Your string
$json = '{"2018-1-8":0,"2018-1-9":0,"2018-1-10":0,"2019-1-1":0,"2019-1-15":0}';
// Get it as an array
$data = json_decode($json, true);
// Pass by reference
foreach ($data as $key => &$value) {
// Remove if key contains '2018'
if (strpos($key, '2018') !== false) {
unset($data[$key]);
}
}
// Return the updated JSON
echo json_encode($data);
// Output: {"2019-1-1":0,"2019-1-15":0}
Another solution using array_walk():
$data = json_decode($json, true);
array_walk($data, function ($v, $k) use (&$data) {
if (strpos($k, '2018') !== false) { unset($data[$k]); }
});
echo json_encode($data);
// Output: {"2019-1-1":0,"2019-1-15":0}
See also:
passing by reference
strpos()
unset()
json_encode()
Try this maybe :
// Your string
$string = "{\"2018-1-8\":0,\"2018-1-9\":0,\"2018-1-10\":0,\"2019-1-1\":0,\"2019-1-15\":0}";
// Transform it as array
$array = json_decode($string);
// Create a new array
$new_array = array();
// Now loop through your array
foreach ($array as $date => $value) {
// If the first 4 char of your $date is not 2018, then add it in new array
if (substr($date, 0, 4) !== "2018")
$new_array[$date] = $value;
}
// Now transform your new array in your desired output
$new_string = json_encode($new_array);
Output of var_dump($new_string); is {"2019-1-1":0,"2019-1-15":0}
I have custom cms database and get parameter from database and my result this is:
$param = 'param1="value1"|param2="value2"|param3="value3"|param4="value4"|param5="value5"'
but I need get param1 value or other value. I try use explode but my result this is:
$string = explode('|',$param);
result:
array (size=4)
0 => string 'param1="value1"'
1 => string 'param2="value2"'
2 => string 'param3="value3"'
3 => string 'param4="value4"'
4 => string 'param5="value4"'
I need get value this format:
$param->param1 = value1;
You also need to explode each of the substrings on =, and then map the results into an array:
$param = 'param1="value1"|param2="value2"|param3="value3"|param4="value4"|param5="value5"';
$params = explode('|', $param);
$results = [];
foreach ($params as $element) {
list($key, $value) = explode('=', $element, 2);
$results[$key] = json_decode($value);
}
echo $results['param1']; // value1
The call to json_decode might look a bit out of place here, but it's the quickest way to convert a quoted string into a native PHP string. The additional argument to the second explode call is to limit the result to two variables, in case the value itself contains an equals sign.
Try parse_str, you can then create an object using the array
<?php
$param = 'param1="value1"|param2="value2"|param3="value3"|param4="value4"|param5="value5"';
$params = array();
parse_str(str_replace('|', '&', $param), $params);
$params = (object) $params;
echo $params->param1;
?>
Nice and easy with a litte regex:
$param = 'param1="value1"|param2="value2"|param3="value3"|param4="value4"|param5="value5"';
$strings = explode('|', $param);
foreach ($strings as $string) {
preg_match('#param\d="(?<value>.+)"#', $string, $matches);
var_dump($matches['value']);
}
The regex #param\d="(?<value>.+)"# looks for param followed by a number then an equals, and we create a named capture group with ?<value> in the brackets.
The output from the var_dumps looks like this:
string(6) "value1"
string(6) "value2"
string(6) "value3"
string(6) "value4"
string(6) "value5"
Try it here https://3v4l.org/bomO7
When you've split the first part using '|', you can convert the rest as though it was a CSV field with '=' as the divider. This deals with quotes and other elements.
<?php
error_reporting ( E_ALL );
ini_set ( 'display_errors', 1 );
$param = 'param1="value1"|param2="value2"|param3="value3"|param4="value4"|param5="value5"';
$parms = explode('|', $param );
$values = [];
foreach ( $parms as $parm ) {
list($key, $value) = str_getcsv($parm, "=");
$values[$key] = $value;
}
print_r($values);
$param = 'param1="value1"|param2="value2"|param3="value3"|param4="value4"|param5="value5"';
$param = json_decode('{"' . str_replace(['=', '|'], ['":', ',"'], $param) . '}');
print_r($param);
This is just example. Don't use it in production :)
Use the following approach:
$param = 'param1="value1"|param2="value2"|param3="value3"|param4="value4"|param5="value5"';
$result = [];
foreach (explode('|', $param) as $item) {
list($k,$v) = explode('=', $item);
$result[$k] = trim($v, '"');
}
$result = (object) $result;
// as you wanted
print_r($result->param1); // value1
I am getting following response in JSON format and I want it to convert it into PHP variables.
JSON:
{"CreateTransactionResponse":{"CreateTransactionResult":{"TransportKey":"aa900d54-7bfb-47e9-a5de-e423ec34a900"
,"ValidationKey":"fbb28b32-f439-4801-a434-99c70aa388ca","Messages":{}}}}
output should be PHP:
$transkey = aa900d54-7bfb-47e9-a5de-e423ec34a900;
$vkey = fbb28b32-f439-4801-a434-99c70aa388ca
please advice me how to do it.
Just simply use json_decode();
$result= json_decode($jSon);
var_dump($result); // to see the output
json to array(json_decode) and then extract from array.
$arr = json_decode($json, true);
extract($arr);
var_dump($CreateTransactionResponse);
Output:
array (size=1)
'CreateTransactionResult' =>
array (size=3)
'TransportKey' => string 'aa900d54-7bfb-47e9-a5de-e423ec34a900' (length=36)
'ValidationKey' => string 'fbb28b32-f439-4801-a434-99c70aa388ca' (length=36)
'Messages' =>
array (size=0)
empty
More about extract
use $CreateTransactionResult['TransportKey'] to access Transport Key from JSON. Similarly $CreateTransactionResult['ValidationKey'] for Validation Key.
If you want to access your json try to decode it first:
$result = json_decode($yourJSON, true);
foreach($result['CreateTransactionResponse'] as $key => $val){
echo $transkey = 'TransportKey= ' . $val['TransportKey'] . '<br/>;
echo $vkey = 'ValidationKey= ' . $val['ValidationKey'];
}
Or if it is an array of JSON's
$result = json_decode($yourJSON, true);
$data = [];
foreach($result['CreateTransactionResponse'] as $key => $val){
$data[] = [
'TransportKey' => $val['TransportKey'],
'ValidationKey' => $val['ValidationKey']
];
}
print_r($data);
try this code it will work
$JSON='{"CreateTransactionResponse":{"CreateTransactionResult":{"TransportKey":"aa900d54-7bfb-47e9-a5de-e423ec34a900" ,"ValidationKey":"fbb28b32-f439-4801-a434-99c70aa388ca","Messages":{}}}}';
$arr=json_decode($JSON, TRUE);
foreach ($arr as $value) {
foreach ($arr['CreateTransactionResponse'] as $key => $var) {
echo 'TransportKey = '.$var['TransportKey'].'<br>';
echo 'ValidationKey = '.$var['ValidationKey'].'<br>';
foreach ($var['Messages'] as $key => $msg) {
echo 'Messages = '.$msg.'<br>';
}
}
}
In this case,If its a single and TransportKey and a single ValidationKey value (not an array/object is passed) at a time, this is the simplest. Else if object contains objects or inside objects that we want to use or convert to variable, should use a foreach to loop through the object.
//Debuggig
//The string you provided is converted to a json object
//In your case if it is a json object already pass directly it to $j
//below is just for debugging and understanding
//$json='{"CreateTransactionResponse":{"CreateTransactionResult":{"TransportKey":"aa900d54-7bfb-47e9-a5de-e423ec34a900","ValidationKey":"fbb28b32-f439-4801-a434-99c70aa388ca","Messages":{}}}}';
//$j=json_decode($json);
$transkey=$j->CreateTransactionResponse->CreateTransactionResult->TransportKey;
$vkey=$j->CreateTransactionResponse->CreateTransactionResult->ValidationKey;
echo $transkey."</br>";
echo $vkey."<br/>";
/*result as said:
aa900d54-7bfb-47e9-a5de-e423ec34a900
fbb28b32-f439-4801-a434-99c70aa388ca
*/
I got stuck somehow on the following problem:
What I want to achieve is to merge the following arrays based on key :
{"Entities":{"submenu_id":"Parents","submenu_label":"parents"}}
{"Entities":{"submenu_id":"Insurers","submenu_label":"insurers"}}
{"Users":{"submenu_id":"New roles","submenu_label":"newrole"}}
{"Users":{"submenu_id":"User - roles","submenu_label":"user_roles"}}
{"Users":{"submenu_id":"Roles - permissions","submenu_label":"roles_permissions"}}
{"Accounting":{"submenu_id":"Input accounting data","submenu_label":"new_accounting"}}
Which needs to output like this:
[{"item_header":"Entities"},
{"list_items" :
[{"submenu_id":"Parents","submenu_label":"parents"},
{"submenu_id":"Insurers","submenu_label":"insurers"}]
}]
[{"item_header":"Users"},
{"list_items" :
[{"submenu_id":"New roles","submenu_label":"newrole"}
{"submenu_id":"User - roles","submenu_label":"user_roles"}
{"submenu_id":"Roles - permissions","submenu_label":"roles_permissions"}]
}]
[{"item_header":"Accounting"},
{"list_items" :
[{"submenu_id":"Input accounting data","submenu_label":"new_accounting"}]
}]
I have been trying all kinds of things for the last two hours, but each attempt returned a different format as the one required and thus failed miserably. Somehow, I couldn't figure it out.
Do you have a construction in mind to get this job done?
I would be very interested to hear your approach on the matter.
Thanks.
$input = array(
'{"Entities":{"submenu_id":"Parents","submenu_label":"parents"}}',
'{"Entities":{"submenu_id":"Insurers","submenu_label":"insurers"}}',
'{"Users":{"submenu_id":"New roles","submenu_label":"newrole"}}',
'{"Users":{"submenu_id":"User - roles","submenu_label":"user_roles"}}',
'{"Users":{"submenu_id":"Roles - permissions","submenu_label":"roles_permissions"}}',
'{"Accounting":{"submenu_id":"Input accounting data","submenu_label":"new_accounting"}}',
);
$input = array_map(function ($e) { return json_decode($e, true); }, $input);
$result = array();
$indexMap = array();
foreach ($input as $index => $values) {
foreach ($values as $k => $value) {
$index = isset($indexMap[$k]) ? $indexMap[$k] : $index;
if (!isset($result[$index]['item_header'])) {
$result[$index]['item_header'] = $k;
$indexMap[$k] = $index;
}
$result[$index]['list_items'][] = $value;
}
}
echo json_encode($result);
Here you are!
In this case, first I added all arrays into one array for processing.
I thought they are in same array first, but now I realize they aren't.
Just make an empty $array=[] then and then add them all in $array[]=$a1, $array[]=$a2, etc...
$array = '[{"Entities":{"submenu_id":"Parents","submenu_label":"parents"}},
{"Entities":{"submenu_id":"Insurers","submenu_label":"insurers"}},
{"Users":{"submenu_id":"New roles","submenu_label":"newrole"}},
{"Users":{"submenu_id":"User - roles","submenu_label":"user_roles"}},
{"Users":{"submenu_id":"Roles - permissions","submenu_label":"roles_permissions"}},
{"Accounting":{"submenu_id":"Input accounting data","submenu_label":"new_accounting"}}]';
$array = json_decode($array, true);
$intermediate = []; // 1st step
foreach($array as $a)
{
$keys = array_keys($a);
$key = $keys[0]; // say, "Entities" or "Users"
$intermediate[$key] []= $a[$key];
}
$result = []; // 2nd step
foreach($intermediate as $key=>$a)
{
$entry = ["item_header" => $key, "list_items" => [] ];
foreach($a as $item) $entry["list_items"] []= $item;
$result []= $entry;
}
print_r($result);
I would prefer an OO approach for that.
First an object for the list_item:
{"submenu_id":"Parents","submenu_label":"parents"}
Second an object for the item_header:
{"item_header":"Entities", "list_items" : <array of list_item> }
Last an object or an array for all:
{ "Menus: <array of item_header> }
And the according getter/setter etc.
The following code will give you the requisite array over which you can iterate to get the desired output.
$final_array = array();
foreach($array as $value) { //assuming that the original arrays are stored inside another array. You can replace the iterator over the array to an iterator over input from file
$key = /*Extract the key from the string ($value)*/
$existing_array_for_key = $final_array[$key];
if(!array_key_exists ($key , $final_array)) {
$existing_array_for_key = array();
}
$existing_array_for_key[count($existing_array_for_key)+1] = /*Extract value from the String ($value)*/
$final_array[$key] = $existing_array_for_key;
}