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?
>Solution :
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.
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.