curiousman
curiousman

Reputation: 67

PHP. change value in Array of Arrays not working

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.

Upvotes: 1

Views: 176

Answers (1)

Don&#39;t Panic
Don&#39;t Panic

Reputation: 41810

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'] ='';
    ...
}

Upvotes: 3

Related Questions