very weird issue: I try to change a json string using json_encode and json_decode. I converted the json string to an array(actually it's array of arrays) and try to change some data in it. but I couldn't get the data changed in inner array somehow.
$jsondata = ' {
"Id": "0400006",
"LastName": "Lincoln",
"FirstName": "Abraham",
"PreferredName": "Mr. Abraham Lincoln",
"BirthDate": "1992-06-20T00:00:00",
"PreferredEmailAddress": null,
"Addresses": [
{
"AddressId": "297143",
"Type": "Home",
"AddressLines": [
"201 S Grant Ave"
],
"AddressModifier": "",
"City": "Columbus",
"State": "OH",
"PostalCode": "43215",
"County": "049",
"Country": "",
"RouteCode": "",
"PhoneNumbers": [
{
"Number": "614-555-6666",
"Extension": "",
"TypeCode": "HOME"
}
],
"AddressLabel": [
"201 S Grant Ave",
"Columbus, OH 43215"
],
"PersonId": "0400006",
"EffectiveStartDate": "2008-06-13T00:00:00",
"EffectiveEndDate": null,
"IsPreferredAddress": true,
"IsPreferredResidence": true,
"TypeCode": "H",
"CountryCode": ""
},
{
"AddressId": "727032",
"Type": "Web Address",
"AddressLines": [
"285 E. Main Ave",
"Apt B"
],
"AddressModifier": "",
"City": "Columbus",
"State": "OH",
"PostalCode": "43215",
"County": "049",
"Country": "",
"RouteCode": "",
"PhoneNumbers": [
{
"Number": "614-555-6666",
"Extension": "",
"TypeCode": "HOME"
}
],
"AddressLabel": [
"285 E. Main Ave",
"Apt B",
"Columbus, OH 43215"
],
"PersonId": "0400006",
"EffectiveStartDate": "2018-06-25T00:00:00",
"EffectiveEndDate": null,
"IsPreferredAddress": false,
"IsPreferredResidence": false,
"TypeCode": "WEB",
"CountryCode": ""
}
],
"EmailAddresses": [],
"Phones": [
{
"Number": "614-555-6666",
"Extension": "",
"TypeCode": "HOME"
}
],
"AddressConfirmationDateTime": null,
"EmailAddressConfirmationDateTime": null,
"PhoneConfirmationDateTime": null,
"LastChangedDateTime": "2018-06-27T20:42:22Z",
"ChosenFirstName": "",
"ChosenMiddleName": "",
"ChosenLastName": "",
"PersonalPronounCode": "",
"IsDeceased": false
}
';
$newAddressData = [
"address1" => "5857 Newbridge Dr.",
"address2" => "Apt D",
"city" => "Chicago",
"state" => "Illions",
"postalcode" => "23456"
];
public function modifyData($jsonStr, $newAddressData){
$personInfoData = json_decode($jsonStr, true);
$addressArray = $personInfoData['Addresses'];
$webAddressObj = null;
foreach($addressArray as $address){
if($address['Type'] == 'Web Address' ){
$webAddressObj = &$address;
break;
}
}
if($webAddressObj != null){
echo("update it!");
$webAddressObj['AddressId'] ='';
$webAddressObj['PhoneNumbers']=[];
$webAddressObj['AddressLabel'] =[];
$webAddressObj['AddressLines'] =[$newAddressData['address1'], $newAddressData['address2']];
$webAddressObj['EffectiveStartDate']='';//2018-06-25T00:00:00
$webAddressObj['City']=$newAddressData['city'];
$webAddressObj['State']=$newAddressData['state'];
$webAddressObj['PostalCode']=$newAddressData['postalcode'];
}else{
echo("new address");
$newAddress = new AddressInfo();
$newAddress->Type = "Web Address";
$newAddress->TypeCode = "WEB";
$newAddress->AddressLines =[$newAddressData['address1'], $newAddressData['address2']];
$newAddress->EffectiveStartDate ='';
$newAddress->City = $newAddressData['city'];
$newAddress->State=$newAddressData['state'];
$newAddress->PostalCode=$newAddressData['postalcode'];
$newAddressJson = json_encode($newAddress);
$addressArray[] = $newAddressJson;
}
print_r($webAddressObj);
echo "<p>";
print_r($addressArray);
echo "<p>";
return $personInfoData;
}
$personalInfoData = modifyData($jsondata, $newAddressData);
echo json_encode($personalInfoData);
========================================
You'll find out the $personalInfoData didn't get changed.
This: $webAddressObj = &$address; does not create a reference to that element of the original array. It creates a reference to the temporary copy of the element created by foreach. The reference to that copy does stay set after you've broken out of the loop, but making changes to it will not affect the original array.
If you want a reference to the original element, You'll also need to assign $addressArray by reference to begin with.
$addressArray = &$personInfoData['Addresses'];
you'll need to maintain the reference in the foreach loop, like
foreach($addressArray as &$address){
And you'll still need to assign by reference inside the loop as you're currently doing.
$webAddressObj = &$address;
Rather than keeping track of all the references, it may be easier to follow if you refer directly to the original array by key instead.
$webAddressKey = null;
foreach($addressArray as $key => $address){
if($address['Type'] == 'Web Address' ){
$webAddressKey = $key;
break;
}
}
if($webAddressKey != null){
echo("update it!");
$personInfoData['Addresses'][$webAddressKey]['AddressId'] ='';
...
}
Related
I have a trouble with JSON in PHP.
I have a JSON structure like this (with some line is const and some line is variable)
{
"user": {
"lam": {---->variable
"\/lam\/files\/a": { ---->variable
"id": 9, ---->variable
"class": "\\OC\\Files\\Storage\\Swift",
"options": {
"user": "owncloud",
"bucket": "lam-15215156681752265498", ---->variable
"password": "",
"region": "regionOne",
"service_name": "swift",
"tenant": "owncloud",
"timeout": "30",
"url": "http:\/\/controller:5000\/v2.0",
"password_encrypted": "NHBuZHd4azhvZDB6b29oYSu5U7JLrDC3AdZGykzNpDU=" ---->variable
}
}
}
}
}
I don't know how to write this content to file as JSON format like this.
And in a number of case, I must write append to this file and result must like this:
{
"user": {
"lam": {
"\/lam\/files\/a": {
"id": 9,
"class": "\\OC\\Files\\Storage\\Swift",
"options": {
"user": "owncloud",
"bucket": "lam-15215156681752265498",
"password": "",
"region": "regionOne",
"service_name": "swift",
"tenant": "owncloud",
"timeout": "30",
"url": "http:\/\/controller:5000\/v2.0",
"password_encrypted": "NHBuZHd4azhvZDB6b29oYSu5U7JLrDC3AdZGykzNpDU="
}
},
"\/lam\/files\/test": {
"id": 12,
"class": "\\OC\\Files\\Storage\\Swift",
"options": {
"user": "owncloud",
"bucket": "lam-152153961597103330",
"password": "",
"region": "regionOne",
"service_name": "swift",
"tenant": "owncloud",
"timeout": "30",
"url": "http:\/\/controller:5000\/v2.0",
"password_encrypted": "MjdzcDlrenptcG5udzI2MLSQvuGIczY\/SyHZVf9o7e8="
}
}
}
}
}
You could create an array, before to use json_encode():
Here is an example.
// prepare an array with variable (should come from database, or whatever)
$vars = [
[
'user' => 'lam',
'path' => '/lam/files/a',
'id' => 9,
'bucket' => 'lam-15215156681752265498',
'pass' => 'NHBuZHd4azhvZDB6b29oYSu5U7JLrDC3AdZGykzNpDU=',
],
[
'user' => 'lam',
'path' => '/lam/files/test',
'id' => 12,
'bucket' => 'lam-152153961597103330',
'pass' => 'MjdzcDlrenptcG5udzI2MLSQvuGIczY/SyHZVf9o7e8=',
]
];
// prepare data to be encoded.
$data = [];
// iterate over the variables,
foreach ($vars as $var) {
// prepare an array for the options
$options = [
"user" => "owncloud",
"bucket" => $var['bucket'], // fill with current variable
"password" => "",
"region" => "regionOne",
"service_name" => "swift",
"tenant" => "owncloud",
"timeout" => "30",
"url" => "http:\/\/controller:5000\/v2.0",
"password_encrypted" =>$var['pass'], // fill with current variable
];
$userdata = [
'id' => $var['id'], // fill with current variable
'class' => '\\OC\\Files\\Storage\\Swift',
'options' => $options, // append options
];
$name = $var['user'];
$path = $var['path'];
$data['user'][$name][$path] = $userdata ; // append to $data array
}
echo json_encode($data, JSON_PRETTY_PRINT);
Outputs:
{
"user": {
"lam": {
"\/lam\/files\/a": {
"id": 9,
"class": "\\OC\\Files\\Storage\\Swift",
"options": {
"user": "owncloud",
"bucket": "lam-15215156681752265498",
"password": "",
"region": "regionOne",
"service_name": "swift",
"tenant": "owncloud",
"timeout": "30",
"url": "http:\\\/\\\/controller:5000\\\/v2.0",
"password_encrypted": "NHBuZHd4azhvZDB6b29oYSu5U7JLrDC3AdZGykzNpDU="
}
},
"\/lam\/files\/test": {
"id": 12,
"class": "\\OC\\Files\\Storage\\Swift",
"options": {
"user": "owncloud",
"bucket": "lam-152153961597103330",
"password": "",
"region": "regionOne",
"service_name": "swift",
"tenant": "owncloud",
"timeout": "30",
"url": "http:\\\/\\\/controller:5000\\\/v2.0",
"password_encrypted": "MjdzcDlrenptcG5udzI2MLSQvuGIczY\/SyHZVf9o7e8="
}
}
}
}
}
You'll need to work with the data as an array (or object) as PHP won't work directly in JSON;
Get your current data from the file into an array:
$data = json_decode(file_get_contents($pathtojsonfile, true));
Append the new data to the array:
$data[] = $newdata;
Then save the newly appended data back to file.
file_put_contents($pathtojsonfile, json_encode($data));
I am making calls to an API
I have the response as an associative array so that I can use:
$field = $response['nameOfKey'];
However, some of the values for keys are themselves arrays like the following:
{
"Title": "Mr",
"Forenames": "Steve",
"Surname": "Williams",
"CountryOfBirth": 1,
"EmailAddress": "john.doe#email.com",
"EmailType": "Personal",
"BirthDate": "\/Date(632880000000)\/",
"Suffix": null,
"NationalInsuranceNumber": null,
"PrimaryAddress": {
"Address1": "Flat 1",
"Address2": "Oxford Street",
"City": "London",
"County": "London",
"Postcode": "L12456",
"Country": 1
},
"AdditionalAddresses": [
{
"Address1": null,
"Address2": null,
"City": null,
"County": null,
"Postcode": null,
"Country": 0,
"AddressType": 0
}
],
"PrimaryTelephone": {
"Number": "123456789",
"DialingCode": 1,
"TelephoneType": 1
},
"AdditionalTelephone": [
{
"Number": "223456789",
"DialingCode": 2,
"TelephoneType": 2
}
],
"BankAccount": {
"AccountName": "John Doe Account",
"AccountNumber": "123456789",
"SortCode": "123456"
},
"PrimaryCitizenship": {
"CountryOfResidency": 1,
"TaxIdentificationNumber": "AB12CD34EF56"
},
"AdditionalCitizenship": [
{
"CountryOfResidency": 0,
"TaxIdentificationNumber": null
}
],
"ExternalCustomerId": "91",
"ExternalPlanId": "91",
"PlanType": 10
}
So at the moment to get Forename I can just do $forename = $decodedResponse["Forenames"]; but I'm quite baffled at trying to get values from the inner arrays.
I thought I could do something like this:
foreach($decodedResponse as $data)
{
foreach($data['TelephoneNumbers'] as $tel)
{
echo $tel['Number']; die();
}
}
Essentially loop through the original Associative array and then loop through a specific key to get its values.
Your should use foreach for following array items: AdditionalAddresses, AdditionalTelephone and AdditionalCitizenship. Otherwise just chain array keys. See examples:
$forename = $decodedResponse['Forenames'];
$address2 = $decodedResponse['PrimaryAddress']['Address2'];
foreach ($decodedResponse['AdditionalTelephone'] as $tel) {
echo $tel['Number'];
}
I'm currently using the Adobe Echosign API to format some data in a table. The output looks like this:
{
"agreementId": "",
"events": [
{
"actingUserEmail": "",
"actingUserIpAddress": "",
"date": "date",
"description": "",
"participantEmail": "",
"type": "",
"versionId": ""
}
],
"locale": "",
"modifiable": false,
"name": "",
"nextParticipantSetInfos": [
{
"nextParticipantSetMemberInfos": [
{
"email": "",
"waitingSince": "date"
}
]
}
],
"participantSetInfos": [
{
"participantSetId": "",
"participantSetMemberInfos": [
{
"email": "",
"participantId": ""
}
],
"roles": [
""
],
"status": ""
}
],
"status": "",
"vaultingEnabled": false
}
I'm looping through multiple agreements and this outputs them each as a separate array.
This is probably a really basic question, but how would I go through each array and extract say the 'participantEmail', 'name' and 'status' values?
Thanks!
Depending on what programming language you are using, there are a lot of ways to handle this. In JS you could convert this JSON array into JS Array of Objects and after that you can access them using JS processing.
Example for JS would be:
var input = 'yourJSONstring';
var jsObject = JSON.parse(input);
for(var foo in jsObject){
var name = foo.name;
var participantEmail= foo.events[0].participantEmail;
var status = foo.participantEmail[0].status;
}
Supposing that you have an array of agreements with the format you provided, you could do something like this:
<?php
$json = '[{
"agreementId": "",
"events": [
{
"actingUserEmail": "",
"actingUserIpAddress": "",
"date": "date",
"description": "",
"participantEmail": "an email",
"type": "",
"versionId": ""
}
],
"locale": "",
"modifiable": false,
"name": "a name",
"nextParticipantSetInfos": [
{
"nextParticipantSetMemberInfos": [
{
"email": "",
"waitingSince": "date"
}
]
}
],
"participantSetInfos": [
{
"participantSetId": "",
"participantSetMemberInfos": [
{
"email": "",
"participantId": ""
}
],
"roles": [
""
],
"status": "a status"
}
],
"status": "",
"vaultingEnabled": false
}]';
$parsed = json_decode($json, true);
$names = [];
foreach($parsed as $agreement) {
$names[] = $agreement['name'];
$emails = [];
foreach($agreement['events'] as $event) {
$emails[] = $event['participantEmail'];
}
$status = [];
foreach($agreement['participantSetInfos'] as $participant) {
$status[] = $participant['status'];
}
}
var_dump($names);
var_dump($emails);
var_dump($status);
Of course you should do some checks for empty values and so, but just to give you an idea.
Since you do not clarify the relation between name, status and email, i just took them in separate arrays, but that's nothing that can't be fixed with some array handling.
Hope this helps!
I have an Mongo Collection that looks like this
{
"_id": ObjectId("0000000000000123"),
"user_id": NumberLong(000010),
"location": {
"addresses": [{
"number": NumberLong(4410),
"street": "Test Drive",
"county": "New York County",
"city": "New York",
"state": "NY",
"zip": "00001",
"links": [{
"image": "http://www.google.com/test",
"datetime": " 11/24/1952"
}, {
"image": "http://www.google.com/test2",
"datetime": " 11/24/1990"
}
]
}
]
}
}
I need to be able to search for the links array for documents with www.google.com and be able to change it to www.yahoo.com
I tried a few versions of mongo's update but no success
$search_string = new MongoRegex("/www.google.com/i");
$collection->update(
array('location.addresses.links.image' => $search_string),
array('$set' => array('location.addresses.$.links.$.image' => '')),
array("multiple" => true)
);
So after more digging I found that the update position operator ($) can only be used one level deep.
So I decided to use foreach statements by reference to get what i needed done
$collection = new MongoCollection($this->db, 'users');
$search_string = new MongoRegex("/www.google.com/i");
$cursor = $collection->find(array('location.addresses.links.image' => $search_string));
foreach ($cursor as $doc)
{
foreach ($doc['location']['addresses'] as &$address)
{
foreach($address['links'] as &$link)
{
$link['image'] = str_replace('www.google.com', 'www.yahoo.com', $offender['image']);
}
}
$collection->update(array("_id" => $doc['_id']), $doc);
}
My contents of MongoDB(when i used find()) is like this:
{
"_id": ObjectId("50072b17b4a6de3b11000001"),
"addresses": [
{
"_id": ObjectId("50072b17b4a6de3b11000004"),
"address1": "770 27th Ave",
"address2": null,
"city": "San Mateo",
"country": "United States",
"country_code": "US",
"name": "home",
"primary": true,
"state": "California",
"zip": "94403"
}
],
"biography": null,
"category_ids": [],
"department": null,
"emails": [
{
"_id": ObjectId("50072b17b4a6de3b11000003"),
"_type": "Email",
"name": "work",
"email": "alan#altimetergroup.com"
}
]
}
What I need to do is I need to update this MongoDB with additional datas's. For that I need to get the values in php as an array and insert that array in to this collection. How to get the values for these specified fields as an array in php and how to insert those in php??
$array = $this->collection->findOne(array('_id' => MONGO_ID));
//Update things
$this->collection->update(array('_id' => $array['_id']), $array);
MONGO_ID in my example should represent the '_id' MongoDB automatically assigns. Make sure it is sent as an Object, and not as a string.
If you want to add another entry, you add an entry like so:
$this->collection->insert($array_of_data, array('safe' => true));
For insert:
$id = new MongoId();
$test->insert(array('t' => 'test', 'email' => array('_id' => $id, 'email' => 'ccc#ccc.com')));
And the result:
{ "_id" : ObjectId("5088cba86527044a31000001"), "t" : "test", "email" : { "_id" : ObjectId("5088cba86527044a31000000"), "email" : "ccc#ccc.com" } }
It works :)