mschofield
mschofield

Reputation: 45

How do you remove arrays containing a string from an object?

Sorry, I am not even quite sure how to phrase my question.

I am trying remove personal registrant information from a public JSON API with a strange setup. Example:

"posts" : [
  {
  "id": 9658,
  "type": "event",
  "custom_fields" : {
    "registered_person_0_name" : [ "John" ],
    "registered_person_1_name" : [ "Doe" ]
  } 

If it helps, this is the var_dump:

["custom_fields"]=>
  object(stdClass)#6601 (45) {
    ["registered_person_0_name"]=>
      array(1) {
        [0]=> string(8) "Beverley"
      }

There is an unknown number of registrants depending on the event, and each field increments as demonstrated. I figured I would unset() all instances of "registered_person," but I am stumped.

If given $posts, I feel like I could do something like:

foreach ( $posts as $post ) {
  unset( $post->custom_fields->all_the_registered_persons_fields_that_match)
}

But I can't quite figure it out. I have attempted typecasting the custom_fields object as an array and using in_array, then unset, but that doesn't seem to work.

I appreciate any pointers. Let me know if I can offer further information.

Upvotes: 0

Views: 66

Answers (3)

Barmar
Barmar

Reputation: 780899

Loop through the property variables and unset them if they match the pattern.

foreach ($posts as $post) {
    $custom_fields = $post->custom_fields;
    foreach (get_object_vars($custom_fields) AS $name => $val) {
        if (preg_match('/^registered_person_\d+_name$/', $name)) {
            unset($custom_fields->{$name});
        }
    }
}

Another option is to use the optional argument to json_decode() so that it returns associative arrays rather than objects. Then you can just use foreach on the array.

foreach ($posts as &$post) {
    $custom_fields = &$post['custom_fields'];
    foreach ($custom_fields AS $name => $val) {
        if (preg_match('/^registered_person_\d+_name$/', $name)) {
            unset($custom_fields[$name]);
        }
    }
}

Note that in this case you have to use reference variables, because assigning arrays normally makes copies.

Upvotes: 3

Don't Panic
Don't Panic

Reputation: 41810

If you use json_decode($the_api_data, true) to get the results array style instead of object style, then you can use array_filter to remove the unwanted keys.

foreach ($posts as &$post) {  // need to use a reference here for this to work
    $post['custom_fields'] = array_filter($post['custom_fields'], function($key){
        return 'registered_person_' != substr($key, 0, 18);
    }, ARRAY_FILTER_USE_KEY);
}

Upvotes: 0

Cristik
Cristik

Reputation: 32785

Assuming you have an array with the fields you want removed, you can use ->{$propName} to achieve this. ->{$someVar} allows you to dynamically access properties of an object.

For example:

$field1 = "name";
echo($object->{$field}) // will echo the name property

In your case:

$sensibleFields = ['creditCardNumber', 'socialSecurityNumber'];
foreach ($posts as $post) {
    foreach ($sensibleFields as $fieldName) {
        unset($post->{$fieldName});
    }
}

Upvotes: 0

Related Questions