2

I want to change key name in a multidimensional array.

My array:

Array
(
    [0] => Array
        (
            [id] => 1
            [fruit namé] => Banana
        )
    [1] => Array
        (
            [id] => 2
            [fruit namé] => Apple
        )
)

My function:

function renameFields($old, $new, $arr) {
    foreach ($arr as $k=>$v) {
        $arr[$k][$new] = $arr[$k][$old];
        unset($arr[$k][$old]);
    }
}

renameFields("fruit namé", "name", $arr);

-

It works for id but not when there an accent like fruit namé.

-

EDIT
I know it's a bad practice to have some special char as key, but this datas came from a French system...

  • Why are you doing `global $arr;` if you are passing `$arr` to your function? – gen_Eric Aug 31 '15 at 19:52
  • I've removed it from the function. –  Aug 31 '15 at 19:54
  • possible duplicate of [In PHP, how do you change the key of an array element?](http://stackoverflow.com/questions/240660/in-php-how-do-you-change-the-key-of-an-array-element) – Pavlin Aug 31 '15 at 19:56

2 Answers2

2

You need to either a) pass $arr to your function by reference or b) have renameFields return the updated array.

Your code currently modifies a copy of the $arr array (because that's what gets passed to renameFields when it's called), and never updates the one that exists outside of the renameFields function.

So, you need to either do:

function renameFields($old, $new, &$arr) {
    foreach ($arr as $k=>$v) {
        $arr[$k][$new] = $arr[$k][$old];
        unset($arr[$k][$old]);
    }
}

renameFields("fruit name", "name", $arr);

Which will pass $arr by reference.

Or:

function renameFields($old, $new, $arr) {
    foreach ($arr as $k=>$v) {
        $arr[$k][$new] = $arr[$k][$old];
        unset($arr[$k][$old]);
    }

    return $arr;
}

$arr = renameFields("fruit name", "name", $arr);

Which will have the function return the updated array and then you need to then update the variable.

P.S. You don't need global $arr; in either case here.

gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • Both solutions made the same. The `fruit name` is still here, and it added at the end of the array a new key called `name`. –  Aug 31 '15 at 20:00
  • @pocpoc: Both worked fine for me: http://codepad.org/49Uyac6k and http://codepad.org/cETp3doJ – gen_Eric Aug 31 '15 at 20:01
  • Since he is using global in the original function, it shouldn't be a copy of the array, but the actual array itself that he is modifying. However, this would be the more correct way. – Jonathan Kuhn Aug 31 '15 at 20:04
  • Hum... Strange. I will look into this. –  Aug 31 '15 at 20:06
  • @JonathanKuhn: But would the `global $arr;` conflict with the `$arr` parameter? – gen_Eric Aug 31 '15 at 20:07
  • As my array comes from a French system, my real key got some accent. In this case, the two solution will not work. Do you know why? Thanks. –  Aug 31 '15 at 20:17
  • `global $arr` would mean that looping over and modifying `$arr` in the function makes the changes to the array outside of the function. In fact, op's original function works fine. http://codepad.viper-7.com/TxldcG – Jonathan Kuhn Aug 31 '15 at 20:18
  • @JonathanKuhn: yes except for the accent. –  Aug 31 '15 at 20:20
  • 1
    @pocpoc You would need to spell the strings you pass into the function exactly as they exist in the array, with accent characters and case exactly the same. Unless you wanted to loop over each sub-key and check it's value in a case insensitive/translit method. – Jonathan Kuhn Aug 31 '15 at 20:20
  • @JonathanKuhn: My question was whether `global $arr;` and the fact that `$arr` was the 3rd parameter would conflict. – gen_Eric Aug 31 '15 at 20:20
  • 1
    @pocpoc without sample data that covers the exact scenario with the issue, then we can't do much more as from what we have, the function works fine. And @Rocket, I have no idea. I just tried modifying OP's function by adding a 3rd parameter and it didn't seem to cause any issues. http://codepad.viper-7.com/m6XFez shows that calling `global` actually overwrites the array inside of the function with the global one and after the loop it modifies the global array, not the one passed in. – Jonathan Kuhn Aug 31 '15 at 20:28
  • @JonathanKuhn: Oh, then I guess OP's original code worked and the *real* issue is the UTF8/accented character issue. – gen_Eric Aug 31 '15 at 20:30
  • @RocketHazmat: your guess right. I've changed few minutes ago the question. For your help. –  Aug 31 '15 at 20:33
  • 1
    Just got me wondering too, if the third argument is passed in by reference will calling global on the variable overwrite the referenced variable with the global one. http://codepad.viper-7.com/Nw4Cep, and it appears that calling global actually breaks the reference making the loop not edit the referenced variable. – Jonathan Kuhn Aug 31 '15 at 20:33
2

It isn't a good idea to use spaces in your key names. You can do it but it's bad practice.

Here is what I came up with:

$my_array = array(
    array(
        'id' => 1,
        'fruit name' => 'Banana'
    ),
    array(
        'id' => 2,
        'fruit name' => 'Apple'
    )
);

function renameFields($old, $new, $arr) {
    $new_a = array();
    foreach ($arr as $a) {
        $new_a[] = array(
            'id' => $a['id'],
            $new => $a[$old] 
        );
    }
    return $new_a;
}

$new_array = renameFields("fruit name", "name", $my_array);

echo "<pre>";
print_r($new_array);
echo "</pre>";

It is a much better idea to pass the array to the function rather than using a global.

GrumpyToaster
  • 335
  • 2
  • 12
  • Why is it "bad practice" to use spaces in key names? – gen_Eric Aug 31 '15 at 20:08
  • php couldn't care less what characters are in a key name. they're just strings, after all. It might be "bad practice" in OTHER languages, like js, where you can use `array.key` as a short-hand access notation, instead of `array[key]`. – Marc B Aug 31 '15 at 20:16
  • I guess it really is NOT bad practice to have spaces in key names but more of a preference. Most companies that set a standards for naming don't use spaces in key names. By not using spaces it just keeps naming conventions standard across the board. – GrumpyToaster Aug 31 '15 at 20:17
  • 1
    most? mayb esome, but not all, and the nice thing about conventions, is that they're like standards: so many to choose from. – Marc B Aug 31 '15 at 20:18