How can I force PHP to use strings for array keys?

get specific key value from array php
php get array($key by value multidimensional)
array_keys
php get array value by key
php array keys to values
php array to string
php array key value
array with key and value

I've come across an old app that uses an id to name type array, for example...

array(1) {
  [280]=>
  string(3) "abc"
}

Now I need to reorder these, and a var_dump() would make it appear that that isn't going to happen while the keys are integers.

If I add an a to every index, var_dump() will show double quotes around the key, my guess to show it is now a string...

array(1) {
  ["280a"]=>
  string(3) "abc"
}

This would let me easily reorder them, without having to touch more code.

This does not work.

$newArray = array();
foreach($array as $key => $value) {
   $newArray[(string) $key] = $value;
}

A var_dump() still shows them as integer array indexes.

Is there a way to force the keys to be strings, so I can reorder them without ruining the array?

EDIT:

I assumed that if they are integers, I can't reorder them without changing the key (which is significant in this example). However, if they were strings, I can reorder them how they like as the index shouldn't be interpreted to have any special meaning. Anyway, see my question update for how I did it (I went down a different route).

Actually they dont have to be in numeric order...

array(208=>'a', 0=> 'b', 99=>'c');

Is perfectly valid if youre assigning them manually. Though i agree the integer keys might be misinterpreted as having a sequential meaning by someone although you would think if they were in a non-numeric order it would be evident they werent. That said i think since you had the leeway to change the code as you updated that is the better approach.


Probably not the most efficient way but easy as pie:

$keys = array_keys($data);

$values = array_values($data);
$stringKeys = array_map('strval', $keys);

$data = array_combine($stringKeys, $values);

//sort your data

A numeric string as array key in PHP, No; no it's not: From the manual: A key may be either an integer or a string. If a key is the standard representation of an integer, it will be interpreted as such (i.e. � You can append the null character "\0" to the end of the array key. This makes it so PHP can’t interpret the string as an integer. All of the array functions (like array_merge ()) work on it. Also not even var_dump () will show anything extra after the string of integers.

YOU CAN'T!!

Strings containing valid integers will be cast to the integer type. E.g. the key "8" will actually be stored under 8. On the other hand "08" will not be cast, as it isn't a valid decimal integer.

Edit:

ACTUALLY YOU CAN!! Cast sequential array to associative array

$obj = new stdClass;
foreach($array as $key => $value){
    $obj->{$key} = $value;
}
$array = (array) $obj;

In most cases, the following quote is true:

Strings containing valid integers will be cast to the integer type. E.g. the key "8" will actually be stored under 8. On the other hand "08" will not be cast, as it isn't a valid decimal integer.

This examples from the PHP Docs

 <?php
    $array = array(
        1    => "a",
        "1"  => "b",
        1.5  => "c",
        true => "d",
    );
    var_dump($array);
?>

The above example will output:

array(1) {
  [1]=> string(1) "d"
}

So even if you were to create an array with numbered keys they would just get casted back to integers.

Unfortunately for me I was not aware of this until recently but I thought I would share my failed attempts.

Failed attempts

$arr = array_​change_​key_​case($arr); // worth a try. 

Returns an array with all keys from array lowercased or uppercased. Numbered indices are left as is.

My next attempts was to create a new array by array_combineing the old values the new (string)keys.

I tried several ways of making the $keys array contain numeric values of type string.

range("A", "Z" ) works for the alphabet so I though I would try it with a numeric string.

$keys = range("0", (string) count($arr) ); // integers

This resulted in an array full of keys but were all of int type.

Here's a couple of successful attempts of creating an array with the values of type string.

$keys = explode(',', implode(",", array_keys($arr))); // values strings

$keys = array_map('strval', array_keys($arr)); // values strings

Now just to combine the two.

$arr = array_combine( $keys, $arr); 

This is when I discovered numeric strings are casted to integers.

$arr = array_combine( $keys, $arr); // int strings
//assert($arr === array_values($arr)) // true. 

The only way to change the keys to strings and maintain their literal values would be to prefix the key with a suffix it with a decimal point "00","01","02" or "0.","1.","2.".

You can achieve this like so.

$keys = explode(',', implode(".,", array_keys($arr)) . '.'); // added decimal point 
$arr = array_combine($keys, $arr);

Of course this is less than ideal as you will need to target array elements like this.

$arr["280."]   

I've created a little function which will target the correct array element even if you only enter the integer and not the new string.

function array_value($array, $key){

    if(array_key_exists($key, $array)){
        return $array[ $key ];
    }
    if(is_numeric($key) && array_key_exists('.' . $key, $array)){
        return $array[ '.' . $key ];
    } 
    return null;
}

Usage

echo array_value($array, "208"); // "abc"

Edit:

ACTUALLY YOU CAN!! Cast sequential array to associative array

All that for nothing

array_change_key_case - Manual, 5, PHP 7). array_change_key_case — Changes the case of all keys in an array return array_map(function($item) use($case) { string(12) "luis@net.com" Questions: I’ve come across an old app that uses an id to name type array, for example… array(1) { [280]=> string(3) "abc" } Now I need to reorder these, and a var_dump() would make it appear that that isn’t going to happen while the keys are integers.

Use an object instead of an array $object = (object)$array;

array_keys - Manual, array_keys() returns the keys, numeric and string, from the array . array_combine() - Creates an array by using one array for keys and another for its values� The reverse action — going from a string to an array — can be done easily with explode, or by using the preg_split function, which takes a regular expression. Using explode. You guessed it: explode is the opposite of implode and uses a delimiter to decide where to break up a string. It is usually the simplest way to break up a string into

You can append the null character "\0" to the end of the array key. This makes it so PHP can't interpret the string as an integer. All of the array functions (like array_merge()) work on it. Also not even var_dump() will show anything extra after the string of integers.

Example:

$numbers1 = array();
$numbers2 = array();
$numbers = array();

$pool1 = array(111, 222, 333, 444);
$pool2 = array(555, 666, 777, 888);

foreach($pool1 as $p1)
{
    $numbers1[$p1 . "\0"] = $p1;
}
foreach($pool2 as $p2)
{
    $numbers2[$p2 . "\0"] = $p2;
}

$numbers = array_merge($numbers1, $numbers2);

var_dump($numbers);

The resulting output will be:

array(8) {
    ["111"] => string(3) "111"
    ["222"] => string(3) "222"
    ["333"] => string(3) "333"
    ["444"] => string(3) "444"
    ["555"] => string(3) "555"
    ["666"] => string(3) "666"
    ["777"] => string(3) "777"
    ["888"] => string(3) "888"
}

Without the . "\0" part the resulting array would be:

array(8) {
    [0] => string(3) "111"
    [1] => string(3) "222"
    [2] => string(3) "333"
    [3] => string(3) "444"
    [4] => string(3) "555"
    [5] => string(3) "666"
    [6] => string(3) "777"
    [7] => string(3) "888"
}

Also ksort() will also ignore the null character meaning $numbers[111] and $numbers["111\0"] will both have the same weight in the sorting algorithm.

The only downside to this method is that to access, for example $numbers["444"], you would actually have to access it via $numbers["444\0"] and since not even var_dump() will show you there's a null character at the end, there's no clue as to why you get "Undefined offset". So only use this hack if iterating via a foreach() or whoever ends up maintaining your code will hate you.

array - Manual, By telling the key to read the object as a string, it will let you set it. So adding $a [5] = 'foo'; after an $a[10] = 'bar'; will not force the next generated if ($asc == 1) { // use first subarrays for new keys of arrays else { // use the last array keys array_keys (array $array, mixed $search_value [, bool $strict = FALSE ]) : array array_keys() returns the keys, numeric and string, from the array. If a search_value is specified, then only the keys for that value are returned. Otherwise, all the keys from the array are returned.

I was able to get this to work by adding '.0' onto the end of each key, as such:

$options = [];
for ($i = 1; $i <= 4; $i++) {
    $options[$i.'.0'] = $i;
}

Will return:

array("1.0" => 1, "2.0" => 2, "3.0" => 3, "4.0" => 4)

It may not be completely optimal but it does allow you to sort the array and extract (an equivalent of) the original key without having to truncate anything.

Arrays - Manual, If multiple elements in the array declaration use the same key, only the last one will be used as all others Always use quotes around a string literal array index. It should be noted that the inverse function to keys (which converts keys to values) is array_count_values (which converts values to keys). This is needed to use things like array_intersect_key. Could go in several places.

How to Convert PHP Arrays to Strings, Convert PHP Arrays to Strings. PHP's implode function returns a string consisting of array element values joined using a string that you specify: $ar = ['apple'� array: Required. Specifies an array: value: Optional. You can specify a value, then only the keys with this value are returned: strict: Optional. Used with the value parameter. Possible values: true - Returns the keys with the specified value, depending on type: the number 5 is not the same as the string "5". false - Default value.

Associative arrays – Hacking with PHP, Specifying your own keys produces what is called an associative array - you associate a specific key with a specific value. Most associative arrays use strings as� I don't think you can go faster than that, I would test if the key actually exist when you go through your array to avoid notices that would slow your script and unwanted null values in your array. The way to go is to use the array_column() function in PHP 5.5 and use the userland implementation of if until you can get 5.5 n your server.

Helpers: ArrayHelper | The Definitive Guide to Yii 2.0, Additionally to the rich set of PHP array functions, the Yii array helper Name of array key or object property to retrieve value from. characters in an array of strings into HTML entities you can use the following: previous array or yii\ helpers\ReplaceArrayValue to force replace former value instead of recursive merging. String keys of associative arrays, for which is_numeric() is true and which can be type-juggled to an int will be cast to an int! If the key is on the other hand a string that can be type-juggled into a float, it will stay a string.

Comments
  • Had the same problem. I got keys like "0", "1" in the input data (from http request) and wanted to filter it by using array_intersect_key... looks like I'll use another approach.
  • Possible duplicate of A numeric string as array key in PHP
  • @Flimm That question was asked after mine, so it's a duplicate of this one.
  • If you want to force the keys to strings, you can, but you can't access them ;) nikic.github.io/2012/03/28/…
  • array_map arguments are around the wrong way. Trying it out now, thanks.
  • Bummer, didn't work. They seem to get cast back to integer. I even tried using the cast operator (string). It is not until I add a non integer that they turn to string.
  • I know it's old, but very annoying issue. Looks that PHP would convert "numeric strings" (?integer strings i suppose) into integers always when creating a key for an array. Here's the bug report: bugs.php.net/bug.php?id=45348&edit=3
  • This literally does nothing; PHP casts your numeric strings straight back to integer keys.
  • It's issues like this that make me want to drop PHP as a tool :/
  • @ÁlvaroGonzález you can iterate any object just like an array, no? It will go through the properties available in the calling scope.
  • @nawfal - You are right, you get all public properties automatically. I wasn't aware of that feature. I'll remove my comment to avoid spreading confusion. Thank you for the pointer.