skip to Main Content

I have a PHP object that I need to change the key name of in a foreach loop:

stdClass Object
(
   [first-name] => NAME
   [last-name] => NAME
   [phone-number] => NUMBER
   ...
)

I need to replace the dash ‘-‘ to a underscore ‘_’ within a foreach so it looks like this:

stdClass Object
(
   [first_name] => NAME
   [last_name] => NAME
   [phone_number] => NUMBER
   ...
)

I found this post: PHP – How to rename an object property? which does tell me how to do it, the problem is that when I use unset() inside of the foreach it unsets all of the keys instead of just the ones I want it to.

Here’s my code:

foreach ($customer as $key => $value) {
    $key2 = str_replace('-', '_', $key);
    $customer->$key2 = $customer->$key;            
    unset($customer->$key);
}

which returns an empty object:

stdClass Object
(
)

How can I unset the original keys without affecting the new ones?

2

Answers


  1. There is a simple trick you can do in general and that is only doing the operation if there is a change:

        $key2 = str_replace('-', '_', $key);
        if ($key2 !== $key) {
            $customer->$key2 = $customer->$key;            
            unset($customer->$key);
        }
    

    You just do nothing if the operation has already been done (by the outcome).

    Within a foreach this can be further "tweaked" by making use of the continue keyword and inversing the comparison:

    foreach ($customer as $key => $value) {
        $key2 = str_replace('-', '_', $key);
        if ($key2 === $key) {
            continue; // nothing to do
        }
        $customer->$key2 = $customer->$key;            
        unset($customer->$key);
    }
    

    But at the end of the day you only don’t want to delete which equals to always set (which works if you unset first and iterate on a clone):

    foreach (clone $customer as $key => $value) {
        $key2 = str_replace('-', '_', $key);
        unset($customer->$key);
        $customer->$key2 = $value;
    }
    

    So choose your weapon, there are even more ways to skin this cat, this just for inspiration. At the end of the day the order of the operations (adding, deleting etc.) is the "key" point.

    All examples on 3v4l.org.

    Login or Signup to reply.
  2. You code almost seems to work, but its a bad idea to work on an object you’re looping through. The solution is get_object_vars() which can get the properties before you loop:

    foreach (get_object_vars($customer) as $key => $value) {
        $key2 = str_replace('-', '_', $key);
        $customer->$key2 = $customer->$key;            
        unset($customer->$key);
    }
    

    See: https://3v4l.org/sfZq3

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search