Updating the value in existing JSON data by key in PHP - php

I have JSON data and want to update the value by key.
JSON:
{
"language":"en",
"education":[
{
"unit":"e1",
"language":"en"
}
],
"membership":[
{
"uei":"21",
"Uifed":"failed"
}
]
}
I want to change the value of uifed from "failed" to "success".
What have I done?
$json = '{"language":"en","education":[{"unit":"e1","language":"en"}],"membership":[{"uei":"21","Uifed":"failed"}]}';
$arrayData = json_decode($json, true);
$replacementData = array('Uifed' => 'success');
$newArrayData = array_replace_recursive($arrayData, $replacementData);
echo var_dump($newArrayData);
Result:
NULL
How can I do that?

That's not how array_replace_recursive works; the replacement arrays need to have the same structure as the one you are replacing into. For your sample data, this will work:
$json = '{"language":"en","education":[{"unit":"e1","language":"en"}],"membership":[{"uei":"21","Uifed":"failed"}]}';
$arrayData = json_decode($json, true);
$replacementData = array('membership' => array(array('Uifed' => 'success')));
$newArrayData = array_replace_recursive($arrayData, $replacementData);
print_r($newArrayData);
Output:
Array
(
[language] => en
[education] => Array
(
[0] => Array
(
[unit] => e1
[language] => en
)
)
[membership] => Array
(
[0] => Array
(
[uei] => 21
[Uifed] => success
)
)
)
array_walk_recursive can be used to do what you want:
$replacementData = array('Uifed' => 'success');
array_walk_recursive($arrayData, function (&$value, $key) use ($replacementData) {
$value = $replacementData[$key] ?? $value;
});
print_r($arrayData);
Output:
Array
(
[language] => en
[education] => Array
(
[0] => Array
(
[unit] => e1
[language] => en
)
)
[membership] => Array
(
[0] => Array
(
[uei] => 21
[Uifed] => success
)
)
)
Demo on 3v4l.org

Simple example with foreach and passing values by reference:
$json = '{"language":"en","education":[{"unit":"e1","language":"en"}],"membership":[{"uei":"21","Uifed":"failed"}]}';
$arrayData = json_decode($json, true);
foreach ($arrayData['membership'] as &$membership) {
if ('failed' === $membership['Uifed']) {
$membership['Uifed'] = 'success';
}
}
print_r($arrayData);
Fiddle.

Related

PHP Removing empty items from object

I have the following object, here printed as an array. This object is built from a SOAP request.
AdminInfo Object (
[Supplier] => Supplier Object (
[Party] => Party Object (
[OrgInfo] => OrgInfo Object (
[CompanyName] => Bobs
[IDInfo] => Array of IDInfo Objects (
[0] => IDInfo Object (
[IDQualifierCode] =>
[IDNum] =>
)
[1] => IDInfo Object (
[IDQualifierCode] => CompanyID
[IDNum] => 83e26599-d40g-4cba-9791-7d7c83de282c
)
[2] => IDInfo Object (
[IDQualifierCode] => TID
[IDNum] => BOBTID01020304
)
[3] => IDInfo Object (
[IDQualifierCode] => Token
[IDNum] => c784570e-044d-42c8-98fe-af9f7c1747f5
)
)
)
[ContactInfo] => ContactInfo Object (
[ContactJobTitle] =>
[Communications] => Comm Object (
[CommQualifier] =>
[CommPhone] =>
[CommEmail] =>
[Address] => Address Object (
[Address1] =>
[Address2] =>
[City] =>
[StateProvince] =>
[PostalCode] =>
[CountryCode] =>
)
)
[ContactName] => PersonName Object (
[FirstName] =>
[MiddleName] =>
[LastName] =>
)
)
)
)
[Company] => Company Object (
[Party] => Party Object (
[OrgInfo] => OrgInfo Object (
[CompanyName] => SF
[IDInfo] =>
)
[ContactInfo] =>
)
)
[Facility] => Facility Object (
[Party] => Party Object (
[OrgInfo] => Array of OrgInfo Objects (
)
[ContactInfo] => ContactInfo Object (
[ContactJobTitle] => Owner
[Communications] => Array of Comm Objects(
[0] => Comm Object (
[CommQualifier] => WP
[CommPhone] => 1234567890
)
[1] => Comm Object (
[CommQualifier] => SA
[Address] => Address Object (
[Address1] => 123 NE 14th St
[City] => Nowhere
[StateProvince] => ND
[PostalCode] => 12345
[CountryCode] => US
)
)
[2] =>
[3] =>
)
[ContactName] => PersonName Object (
[FirstName] => Bob
[MiddleName] =>
[LastName] => Tester
)
)
)
)
)
What I want to do is to remove all the empty elements and be returned with this object
AdminInfo Object (
[Supplier] => Supplier Object (
[Party] => Party Object (
[OrgInfo] => OrgInfo Object (
[CompanyName] => Bobs
[IDInfo] => Array of IDInfo Objects (
[0] => IDInfo Object (
[IDQualifierCode] =>
[IDNum] =>
)
[1] => IDInfo Object (
[IDQualifierCode] => CompanyID
[IDNum] => 83e26599-d40g-4cba-9791-7d7c83de282c
)
[2] => IDInfo Object (
[IDQualifierCode] => TID
[IDNum] => BOBTID01020304
)
[3] => IDInfo Object (
[IDQualifierCode] => Token
[IDNum] => c784570e-044d-42c8-98fe-af9f7c1747f5
)
)
)
)
)
[Company] => Company Object (
[Party] => Party Object (
[OrgInfo] => OrgInfo Object (
[CompanyName] => SF
)
)
)
[Facility] => Facility Object (
[Party] => Party Object (
[ContactInfo] => ContactInfo Object (
[ContactJobTitle] => Owner
[Communications] => Array of Comm Objects (
[0] => Comm Object (
[CommQualifier] => WP
[CommPhone] => 1234567890
)
[1] => Comm Object (
[CommQualifier] => SA
[Address] => Address Object (
[Address1] => 123 NE 14th St
[City] => Nowhere
[StateProvince] => ND
[PostalCode] => 12345
[CountryCode] => US
)
)
)
[ContactName] => PersonName Object (
[FirstName] => Bob
[LastName] => Tester
)
)
)
)
)
These attempts don't do it AT ALL; variable $AdminInfo is the Object above...
From solution here: strip null values of json object
$json = json_encode($AdminInfo);
$result = preg_replace('/,\s*"[^"]+":null|"[^"]+":null,?/', '', $json);
$echo $result;
From solution here: How to remove null values from an array?
$json = json_encode($AdminInfo); // convert to JSON
$arr = (array)json_decode($json); // convert to an array
$object = (object) array_filter((array) $arr); // filter the array
$result = json_encode($object); // convert it back to JSON
echo $result;
From here: PHP - How to remove empty entries of an array recursively?
function array_remove_empty($haystack)
{
foreach ($haystack as $key => $value) {
if (is_array($value)) {
$haystack[$key] = array_remove_empty($haystack[$key]);
}
if (empty($value)) {
unset($haystack[$key]);
}
}
return $haystack;
}
$json = json_encode($AdminInfo); // convert to JSON
$arr = (array)json_decode($json); // convert to an array
print_r(array_remove_empty($arr)); // run through array_remove_empty function and print
From solution here: Remove items from multidimensional array in PHP
function cleanArray($array) {
if (is_array($array)) {
foreach ($array as $key => $sub_array)
{
$result = cleanArray($sub_array);
if ($result === false) {
unset($array[$key]);
} else {
$array[$key] = $result;
}
}
}
if (empty($array)) {
return false;
}
return $array;
}
$json = json_encode($AdminInfo); // convert to JSON
$arr = (array)json_decode($json); // convert to an array
print_r(cleanArray($arr)); // run through cleanArray function and print
Edit
AdminInfo object as JSON:
{
"Supplier":{
"Party":{
"OrgInfo":{
"CompanyName":"Bobs",
"IDInfo":[
{
"IDQualifierCode":null,
"IDNum":""
},
{
"IDQualifierCode":"CompanyID",
"IDNum":"83e26599-d40g-4cba-9791-7d7c83de282c"
},
{
"IDQualifierCode":"TID",
"IDNum":"BOBTID01020304"
},
{
"IDQualifierCode":"Token",
"IDNum":"c784570e-044d-42c8-98fe-af9f7c1747f5"
}
]
},
"ContactInfo":{
"ContactJobTitle":"",
"Communications":{
"CommQualifier":null,
"CommPhone":"",
"CommEmail":"",
"Address":{
"Address1":"",
"Address2":"",
"City":"",
"StateProvince":null,
"PostalCode":"",
"CountryCode":null
}
},
"ContactName":{
"FirstName":"",
"MiddleName":"",
"LastName":""
}
}
}
},
"Company":{
"Party":{
"OrgInfo":{
"CompanyName":"SF",
"IDInfo":null
},
"ContactInfo":null
}
},
"Facility":{
"Party":{
"OrgInfo":[
],
"ContactInfo":{
"ContactJobTitle":"",
"Communications":[
{
"CommQualifier":null,
"CommPhone":"",
"CommEmail":"",
"Address":{
"Address1":"",
"Address2":"",
"City":"",
"StateProvince":null,
"PostalCode":"",
"CountryCode":null
}
},
null,
null,
null
],
"ContactName":{
"FirstName":"Bob",
"MiddleName":"",
"LastName":"Tester"
}
}
}
}
}
Requirements: Recursively scan nested arrays pruning out empty branches / items.
This is another 'tree walk'.
The only 'tricky' part is letting the processing higher up the tree know whether to add the current item into the output tree or not.
The function that processes a node will return an array that has a 'keep value' flag as well as the value to keep.
JSON Converted to array: Full Working code at eval.in
Output preserves original JSON Data Type: Full Working code at eval.in
Code:
function processList(array $list)
{
$listResult = ['keepValue' => false, // once set true will propagate upward
'value' => []];
foreach ($list as $name => $item ) {
if (is_null($item)) { // see is_scalar test
continue;
}
if (is_scalar($item)) { // keep the value?
if (!empty($item) || strlen(trim($item)) > 0) {
$listResult['keepValue'] = true;
$listResult['value'][$name] = $item;
}
} else { // new list... recurse
$itemResult = processList($item);
if ($itemResult['keepValue']) {
$listResult['keepValue'] = true;
$listResult['value'][$name] = $itemResult['value'];
}
}
}
return $listResult;
}
Run the function:
$source = json_decode($json, true);
$result = processList($source);
print_r($result['value']);
Output:
Array
(
[Supplier] => Array
(
[Party] => Array
(
[OrgInfo] => Array
(
[CompanyName] => Bobs
[IDInfo] => Array
(
[1] => Array
(
[IDQualifierCode] => CompanyID
[IDNum] => 83e26599-d40g-4cba-9791-7d7c83de282c
)
[2] => Array
(
[IDQualifierCode] => TID
[IDNum] => BOBTID01020304
)
[3] => Array
(
[IDQualifierCode] => Token
[IDNum] => c784570e-044d-42c8-98fe-af9f7c1747f5
)
)
)
)
)
[Company] => Array
(
[Party] => Array
(
[OrgInfo] => Array
(
[CompanyName] => SF
)
)
)
[Facility] => Array
(
[Party] => Array
(
[ContactInfo] => Array
(
[ContactName] => Array
(
[FirstName] => Bob
[LastName] => Tester
)
)
)
)
)
After a little bit of headscratching I came up with a recursive function that, like I suggested earlier, converts the object into an array to check if the variables are set to null.
If all variables inside that object are null, the parent is indexed to set the reference of the object to null.
I tried to explain and document the code as best as I can.
Please don't just copy the code and be done with it but read it trough and try to learn from the code I supplied.
/**
Unsets all empty variables in $object
*/
function loopTrough(&$object, &$parent = null, $key = null, $objectIsArray = false, $parentIsArray = false)
{
// Keep track of amount of vars and amount of null vars
$vars = 0;
$null = 0;
foreach($object as $index => $value)
{
$vars = $vars + 1;
// Also check if is array
$isArray = is_array($value);
// Check if is object
if (is_object($value) || $isArray) // using value here is save
{
// Loop trough the new object (or array) we found
if ($objectIsArray)
{
loopTrough($object[$index], $object, $index, $isArray, $objectIsArray);
}
else
{
loopTrough($object->{$index}, $object, $index, $isArray, $objectIsArray);
}
}
// Check if is null
if ($objectIsArray)
{
if (!isset($object[$index]) || $object[$index] == ""){
$null = $null + 1;
// We don't want to show null
unset($object[$index]);
}
}
else
{
if (!isset($object->{$index}) || $object->{$index} == "") // use $object->{index} here, and not $value because $value does not change when object reference is changed
{
$null = $null + 1;
// We don't want to show null
unset($object->{$index});
}
}
}
// If there are as much null variables as variables
if ($vars == $null && $parent !== null && $key !== null)
{
// Set the parent reference to null
if ($parentIsArray) // Example exludes arrays, uncomment this if you want values in arrays to be recurisvely set to null
{
// unset($parent[$key]);
}
else
{
unset($parent->{$key});
}
}
}
class Test
{
public $one;
public $two;
}
$test = new Test();
$test->one = new Test();
$test->one->two = "On";
$test->two = new Test();
$test->two->one = new Test();
var_dump($test);
loopTrough($test);
var_dump($test);
Like I suggested earlier you COULD convert the object into an array and recursively loop trough the elements to check if they are null.
The recursive function is going to be quite complicated since you don't just want to remove null variables, but remove everything that contains null only variables.
Heres an example without the recursion which just removes null variables from an object:
class A
{
public $var = "aVar";
public $var1 = null;
}
$a = new A();
var_dump($a);
$array = (array)$a;
foreach($array as $key => $value)
{
if (is_null($value)){
unset($array[$key]);
}
}
var_dump($array);
seriously don't got time to test it, but edit: tested it, had a bug in the original code (had clean_iterable(NULL,$v); instead of clean_iterable(NULL,$v[$key]);, fixed it, this seem to work:
function clean_iterable(Iterable $v=NULL,Iterable &$vv=NULL):Iterable{
if(isset($vv)){
$v=&$vv;
}
if(empty($v)){
return $v;
}
foreach($v as $key=>$val){
if(empty($val)){
unset($v[$key]);
}elseif(is_iterable($val)){
clean_iterable(NULL,$v[$key]);
}
}
return $v;
}

PHP - How do I unset an array index by value inside that index

I have an array of objects ($response) that looks like this:
Array
(
[0] => stdClass Object
(
[CardNumber] => 5897853070424xxx
[CardHolderName] => P Stoltz
[CardHolderContactNumber] =>
[CardHolderEmailAddress] =>
[CardExpiryDate] => 2017-09-01T00:00:00
[CardHolderTypeID] => 2
[LastUsedDate] => 2017-05-25T00:00:00
)
[1] => stdClass Object
(
[CardNumber] => 589785304326xxx
[CardHolderName] => J Stoltz
[CardHolderContactNumber] =>
[CardHolderEmailAddress] =>
[CardExpiryDate] => 2017-09-01T00:00:00
[CardHolderTypeID] => 2
[LastUsedDate] => 2017-05-25T00:00:00
)
)
Now, I need to unset the entire object where CardNumber != '589785304326xxx'
I have tried this:
$cardnumber = '5897853070424xxx';
foreach( $response as $res )
{
if($res->CardNumber != $cardnumber)
{
unset($res);
}
}
This does nothing. Any suggestions?
What you have tried will only unset the current object in the loop. You need to do the following:
foreach($response as $key => $res) {
if($res->CardNumber != $cardnumber) {
unset($response[$key], $res);
continue;
}
}
Use unset() inside the loop.
eg:
unset('key value', 'your array name');

group php array by subarray value

I want to group an array by a subarray's value. If I have an array like this:
Array
(
[0] => Array
(
[userID] => 591407753
[propertyA] => 'text1'
[propertyB] => 205
)
[1] => Array
(
[userID] => 989201004
[propertyA] =>'text2'
[propertyB] => 1407
)
[2] => Array
(
[userID] => 989201004
[propertyA] => 'text3'
[propertyB] => 1407
)
)
I want to sort to group this array by a subarray's value so I can have an array like this:
Array
(
[0]=>Array
(
[userID]=>59140775
[properties]=>Array
(
[0]=>text1
)
[propertyB]=>205
)
[1]=>Array
(
[userID]=>989201004
[properties]=>Array
(
[0]=>'text2'
[1]=>'text3'
)
[propertyB]=>1047
)
)
How can I make this?
Before I had tried this:
$result = array();
foreach ($userArray as $record)
{
$id=$record['userID'];
if(isset($result[$id]))
{
$result[$id]['propertyA'][]=array($record['propertyA']);
}
else {
$record["propertyA"]=array($record['propertyA']);
unset($record['tweet']);
$result[$id]=$record;
}
}
the problem was for the propertyA. I was an the result an additional property propertyA with the table like this:
Array
(
[0]=>Array (
[userID]=>989201004
[propertyA]=>'text2'
[properties]=>Array(
[0]=>'text2'
[1]=>'text3'
)
)
)
The following code should do the job. I hope it is self-explanatory:
$result = array();
foreach ($array as $record) {
if (!isset($result[$record['userID']])) {
$result[$record['userID']] = array(
'userID' => $record['userID'],
'properties' => array($record['propertyA']),
'propertyB' => $record['propertyB'],
);
}
else {
$result[$record['userID']]['properties'][] = $record['propertyA'];
}
}
$result = array_values($result);

convert array value to key

I am working in PHP.
I have one array. i need to create language array like ([CN] => Chinese) this format.
My array response is given below.
Array
(
[0] => stdClass Object
(
[language_name] => Chinese
[language_code] => CN
)
[1] => stdClass Object
(
[language_name] => English
[language_code] => EN
)
[2] => stdClass Object
(
[language_name] => Korea
[language_code] => KO
)
[3] => stdClass Object
(
[language_name] => Vietnamese
[language_code] => VN
)
)
I need to convert this type of array
Array(
[CN]=>Chinese
[EN]=>English
[KO]=>Korea
[VN]=>Vietnamese
)
How can I do this?
Code:
<?php
$newArray = array();
foreach($yourArray as $key => $items) {
$newArray[$items->language_code] = $items->language_name;
}
die('<pre>' . print_r($newArray, true) . '</pre>');
That's it.
Use PHP's foreach :
function convert($array){
$ret = array();
foreach($array as $obj){
$ret[$obj->language_code] = $obj->language_name;
}
return $ret;
}
you could try this:
foreach($objects as $object)
{
$newArray[$object->language_code] = $object->language_name;
}
print_r($newArray);
This code is working fine
foreach($objects as $object)
{
$newArray[$object->language_code] = $object->language_name;
}
echo "<pre>";
print_r($newArray);
echo "</pre>";

Write JSON into a file with PHP

I have this JSON-File here
{
"id" : "bf75b277-169b-49da-8ab1-b78b8dfg1b43-e25c7f28b3",
"ts" : "1372751172664",
"connected" : {
"ssid" : "eduroam",
"bssid" : "00:0f:f9:eb:08:81",
"rssi" : "-62",
"speed" : "53"
},
"configured" : [
{
"ssid" : "eduroam",
"bssid" : "null",
"keyMgmnt" : ["2", "3"],
"grCiphers" : ["0","1","2","3"]
},
{
"ssid" : "foobar",
"bssid" : "null",
"keyMgmnt" : ["0"],
"grCiphers" : ["0","1","2","3"]
}
],
"location" : {
"prov" : "network",
"lat" : "52.3793203",
"lon" : "9.7231332",
"acc" : "22.777"
}
}
and I'm trying to get the key-value-pairs out into a file (and later into a mysql-database).
I am having trouble to go along the nested structure. Maybe I do not understand it correctly?
$LOGPATH = "/var/www/test/";
$out = fopen($LOGPATH."testlog.log", "a");
$result = file_get_contents('php://input');
$data = json_decode($result, true);
$value = $data;
$test = array();
This line beneath causes me headaches, how can I say get the key-value-pairs of "connected"?
Trying $test = $data['connected'] did not work, as the output simply is a "{" and nothing more...
$test = $data;
fwrite($out, "test \n");
fwrite($out, $test);
fwrite($out, "\n");
foreach ($test as $entry){
fwrite($out, $entry);
fwrite($out, "\n");
}
Any idea how to extract the key-value-pairs and/or help me understand the structure?
This should get you on the right track
foreach($data['connected'] as $key => $value){
echo 'Key: '.$key.' Value:'.$value.'<br>';
}
json_decode() will dump JSON into regular array. You can do print_r() or var_dump() on it, to see the structure of the array. So to get your connected leaf you do:
$connected = $data['connected'];
You can then iterate over it:
foreach( $connected as $key=>$val ) {
echo $key . ": " . $val;
}
Got it, thanks to you guys!
// Get a request from i.e. a webpage (this is a webservice)
$jsonArray = file_get_contents('php://input');
// put the JSON-Data into an array
$jsonData = json_decode($jsonArray, true);
// You can simply choose the entry-points. As they do not change for me, they are hardcoded in here, else you had to use something like a for-loop to extract them
$jsonConnect = $jsonData['connected'];
$jsonLocation = $jsonData['location'];
$jsonConfigured = $jsonData['configured'];
// walk through the JSON-Data and extract the values, although the array has more than 2 levels, you can select your entry-point and walk from there on, which makes this quite easy
for($i = 0; $i < count($jsonConfigured); $i++){
// keyMgmnt itself is an array and I want to concatenate all of its values and put it into a single field in my MySQL-DB, so implode() is used
$keyMgmnt = implode(",", $jsonConfigured[$i]['keyMgmnt']);
$grCiphers = implode(",", $jsonConfigured[$i]['grCiphers']);
$ssid = $jsonConfigured[$i]['ssid'];
$bssid = $jsonConfigured[$i]['bssid'];
// from here on I simply put the variables into my MySQL-DB
$sql_configured = "INSERT INTO configured (keyMgmnt, grCiphers, ssid, bssid) VALUES ('$keyMgmnt', '$grCiphers', '$ssid', '$bssid')";
mysql_query($sql_configured) or die ("Failure in configured");
}
$sql_connected = "INSERT INTO connected (rssi, speed, ssid, bssid) VALUES ('$jsonConnect[rssi]', '$jsonConnect[speed]', '$jsonConnect[ssid]', '$jsonConnect[bssid]')";
$enterConnected = mysql_query($sql_connected) or die("Failure in connection!");
$sql_location = "INSERT INTO location (lat, prov, lon, acc) VALUES ('$jsonLocation[lat]', '$jsonLocation[prov]', '$jsonLocation[lon]', '$jsonLocation[acc]')";
$enterLocation = mysql_query($sql_location) or die("Failure in location!");
Thanks again!
Case closed.
PS: The structure of the JSON-Data. You get it by using "print_r()" or "var_dump()".
(
[id] => bf75b277-169b-49da-8ab1-b78b80f51b43-e25c7f28b3
[ts] => 1372751172664
[connected] => Array
(
[ssid] => eduroam
[bssid] => 00:0f:f7:eb:08:81
[rssi] => -62
[speed] => 54
)
[configured] => Array
(
[0] => Array
(
[ssid] => eduroam
[bssid] => null
[keyMgmnt] => Array
(
[0] => 2
[1] => 3
)
[grCiphers] => Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
)
)
[1] => Array
(
[ssid] => foobar
[bssid] => null
[keyMgmnt] => Array
(
[0] => 0
)
[grCiphers] => Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
)
)
)
[location] => Array
(
[prov] => network
[lat] => 52.3793203
[lon] => 9.7231332
[acc] => 22.777
)
)
(
[id] => bf75b277-169b-49da-8ab1-b78b80f51b43-e25c7f28b3
[ts] => 1372751172664
[connected] => Array
(
[ssid] => eduroam
[bssid] => 00:0f:f7:eb:08:81
[rssi] => -62
[speed] => 54
)
[configured] => Array
(
[0] => Array
(
[ssid] => eduroam
[bssid] => null
[keyMgmnt] => Array
(
[0] => 2
[1] => 3
)
[grCiphers] => Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
)
)
[1] => Array
(
[ssid] => foobar
[bssid] => null
[keyMgmnt] => Array
(
[0] => 0
)
[grCiphers] => Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
)
)
)
[location] => Array
(
[prov] => network
[lat] => 52.3793203
[lon] => 9.7231332
[acc] => 22.777
)
)

Categories